mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 06:51:17 +07:00
For #PY-2748 Resolve to argument with redundant parentheses and to binary expression argument in percent string
This commit is contained in:
@@ -91,29 +91,73 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement resolvePercentString() {
|
||||
final PyBinaryExpression binaryExpression = PsiTreeUtil.getParentOfType(getElement(), PyBinaryExpression.class);
|
||||
PsiElement result = null;
|
||||
|
||||
final PyBinaryExpression binaryExpression = PsiTreeUtil.getParentOfType(getElement(), PyBinaryExpression.class);
|
||||
if (binaryExpression != null) {
|
||||
final PyExpression rightExpression = binaryExpression.getRightExpression();
|
||||
if (rightExpression instanceof PyParenthesizedExpression) {
|
||||
final PyParenthesizedExpression expression = (PyParenthesizedExpression)rightExpression;
|
||||
final PyExpression containedExpression = expression.getContainedExpression();
|
||||
if (containedExpression instanceof PyTupleExpression ) {
|
||||
final PyExpression[] elements = ((PySequenceExpression)containedExpression).getElements();
|
||||
if (elements.length > myPosition) {
|
||||
return elements[myPosition];
|
||||
}
|
||||
}
|
||||
result = resolvePositional((PyParenthesizedExpression)rightExpression);
|
||||
}
|
||||
else if (rightExpression instanceof PyDictLiteralExpression) {
|
||||
if (myChunk.getMappingKey() != null) {
|
||||
final PyKeyValueExpression[] keyValueExpressions = ((PyDictLiteralExpression)rightExpression).getElements();
|
||||
for (PyKeyValueExpression keyValueExpression: keyValueExpressions) {
|
||||
final PyStringLiteralExpression key = (PyStringLiteralExpression)keyValueExpression.getKey();
|
||||
if (key.getStringValue().equals(myChunk.getMappingKey())) {
|
||||
return key;
|
||||
}
|
||||
result = resolveKeyword((PyDictLiteralExpression)rightExpression);
|
||||
}
|
||||
}
|
||||
return result == null ? getElement() : result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement resolveKeyword(PyDictLiteralExpression rightExpression) {
|
||||
if (myChunk.getMappingKey() != null) {
|
||||
final PyKeyValueExpression[] keyValueExpressions = rightExpression.getElements();
|
||||
for (PyKeyValueExpression keyValueExpression: keyValueExpressions) {
|
||||
final PyStringLiteralExpression key = (PyStringLiteralExpression)keyValueExpression.getKey();
|
||||
if (key.getStringValue().equals(myChunk.getMappingKey())) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement resolvePositional(PyParenthesizedExpression rightExpression) {
|
||||
PsiElement result = null;
|
||||
|
||||
final PyExpression containedExpression = getContainedExpression(rightExpression);
|
||||
if (containedExpression instanceof PyTupleExpression) {
|
||||
final PyExpression[] elements = ((PySequenceExpression)containedExpression).getElements();
|
||||
if (elements.length > myPosition) {
|
||||
result = elements[myPosition];
|
||||
}
|
||||
}
|
||||
else if (containedExpression instanceof PyBinaryExpression && ((PyBinaryExpression)containedExpression).isOperator("+")) {
|
||||
result = processNotNestedBinaryExpression((PyBinaryExpression)containedExpression);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement processNotNestedBinaryExpression(PyBinaryExpression containedExpression) {
|
||||
PyExpression left = containedExpression.getLeftExpression();
|
||||
PyExpression right = containedExpression.getRightExpression();
|
||||
if (left instanceof PyParenthesizedExpression) {
|
||||
PyExpression leftTuple = getContainedExpression((PyParenthesizedExpression)left);
|
||||
if (leftTuple instanceof PyTupleExpression) {
|
||||
PyExpression[] leftTupleElements = ((PyTupleExpression)leftTuple).getElements();
|
||||
int leftTupleLength = leftTupleElements.length;
|
||||
if (leftTupleLength > myPosition) {
|
||||
return leftTupleElements[myPosition];
|
||||
}
|
||||
if (right instanceof PyParenthesizedExpression) {
|
||||
PyExpression rightTuple = ((PyParenthesizedExpression)right).getContainedExpression();
|
||||
if (rightTuple instanceof PyTupleExpression) {
|
||||
PyExpression[] rigthTupleElements = ((PyTupleExpression)rightTuple).getElements();
|
||||
int rightLength = rigthTupleElements.length;
|
||||
if (leftTupleLength + rightLength > myPosition)
|
||||
return rigthTupleElements[myPosition - leftTupleLength];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +165,15 @@ public class PySubstitutionChunkReference extends PsiReferenceBase<PyStringLiter
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyExpression getContainedExpression(@NotNull final PyParenthesizedExpression parenthesizedExpression) {
|
||||
PyExpression containedExpression = parenthesizedExpression.getContainedExpression();
|
||||
while (containedExpression instanceof PyParenthesizedExpression) {
|
||||
containedExpression = ((PyParenthesizedExpression)containedExpression).getContainedExpression();
|
||||
}
|
||||
return containedExpression;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyArgumentList getArgumentList(final PsiElement original) {
|
||||
final PsiElement pyReferenceExpression = PsiTreeUtil.getParentOfType(original, PyReferenceExpression.class);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
print("<ref>%d%s" % ((("1", " "))))
|
||||
@@ -0,0 +1 @@
|
||||
print("<ref>%d%s" % (("1",) + (" ")))
|
||||
@@ -659,4 +659,17 @@ public class PyResolveTest extends PyResolveTestCase {
|
||||
public void testGlobalNotDefinedAtTopLevel() {
|
||||
assertResolvesTo(PyTargetExpression.class, "foo");
|
||||
}
|
||||
|
||||
//PY-2478
|
||||
public void testPercentStringBinaryStatementArg() {
|
||||
PsiElement target = resolve();
|
||||
assertTrue(target instanceof PyStringLiteralExpression);
|
||||
assertTrue(((PyStringLiteralExpression)target).getStringValue().equals("1"));
|
||||
}
|
||||
|
||||
public void testPercentStringArgWithRedundantParentheses() {
|
||||
PsiElement target = resolve();
|
||||
assertTrue(target instanceof PyStringLiteralExpression);
|
||||
assertTrue(((PyStringLiteralExpression)target).getStringValue().equals("1"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user