diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml index 6cdbf4fa9090..40b3e80d0b29 100644 --- a/python/src/META-INF/python-core-common.xml +++ b/python/src/META-INF/python-core-common.xml @@ -452,6 +452,7 @@ + diff --git a/python/src/com/jetbrains/python/codeInsight/PySubstitutionChunkReference.java b/python/src/com/jetbrains/python/codeInsight/PySubstitutionChunkReference.java index ddbe2fc3e24d..898c1f9aa335 100644 --- a/python/src/com/jetbrains/python/codeInsight/PySubstitutionChunkReference.java +++ b/python/src/com/jetbrains/python/codeInsight/PySubstitutionChunkReference.java @@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable; public class PySubstitutionChunkReference extends PsiReferenceBase implements PsiReferenceEx{ private final int myPosition; private final PyStringFormatParser.SubstitutionChunk myChunk; + private boolean myIgnoreUnresolved = false; public PySubstitutionChunkReference(@NotNull final PyStringLiteralExpression element, @NotNull final PyStringFormatParser.SubstitutionChunk chunk, final int position) { @@ -37,10 +38,11 @@ public class PySubstitutionChunkReference extends PsiReferenceBase 0) { final PyExpression[] arguments = argumentList.getArguments(); - if (myChunk.getMappingKey() != null) { + + boolean isStarArgument = arguments.length == 1 && arguments[0] instanceof PyStarArgument; + if (isStarArgument) return getUnderStarExpression(arguments); + + boolean isKeywordSubstitution = myChunk.getMappingKey() != null; + if (isKeywordSubstitution) { return argumentList.getKeywordArgument(myChunk.getMappingKey()); } else { final int position = myChunk.getPosition() == null ? myPosition : myChunk.getPosition(); - if (arguments.length == 1 && arguments[0] instanceof PyStarArgument) { - return arguments[0]; - } - else if (position < arguments.length) { - return arguments[position]; - } + if (position < arguments.length) return arguments[position]; + + if (arguments[0] instanceof PyBinaryExpression && ((PyBinaryExpression)arguments[0]).isOperator("+")) { + return processNotNestedBinaryExpression((PyBinaryExpression)arguments[0]); } } + } return null; } @@ -94,24 +102,27 @@ public class PySubstitutionChunkReference extends PsiReferenceBase myPosition) { - result = elements[myPosition]; + if (expression instanceof PyParenthesizedExpression) { + final PyExpression containedExpression = getContainedExpression((PyParenthesizedExpression)expression); + + 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); + } + else if (containedExpression instanceof PyReferenceExpression) { + myIgnoreUnresolved = true; } } - else if (containedExpression instanceof PyBinaryExpression && ((PyBinaryExpression)containedExpression).isOperator("+")) { - result = processNotNestedBinaryExpression((PyBinaryExpression)containedExpression); + else if (expression instanceof PyReferenceExpression) { + myIgnoreUnresolved = true; } return result; } @@ -154,10 +174,10 @@ public class PySubstitutionChunkReference extends PsiReferenceBase myPosition) - return rigthTupleElements[myPosition - leftTupleLength]; + return rightTupleElements[myPosition - leftTupleLength]; } } } @@ -180,9 +200,57 @@ public class PySubstitutionChunkReference extends PsiReferenceBase