diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index 30aab5fd9d56..8a9f5d081434 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -702,6 +702,7 @@ + diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 57f274200ec8..251a858ccafb 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -567,7 +567,8 @@ runcfg.unittest.incorrect.script=Test script name should start with "test" prefi runcfg.unittest.dlg.tests_group_title=Tests: runcfg.unittest.dlg.test_script_label=Script: runcfg.unittest.dlg.class_label=Class: -runcfg.unittest.dlg.method_label=Function: +runcfg.unittest.dlg.method_label=Method: +runcfg.unittest.dlg.function_label=Function: runcfg.unittest.dlg.folder_path=Folder: runcfg.unittest.dlg.test_type_title=Test: runcfg.unittest.dlg.all_in_folder_title=All in folder diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java index 880f8957103b..419bed790833 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java @@ -37,7 +37,9 @@ public class PyDictKeyNamesCompletionContributor extends CompletionContributor { int offset = parameters.getOffset(); final CompletionResultSet dictCompletion = createResult(original, result, offset); - PsiElement operand = PsiTreeUtil.getParentOfType(original, PySubscriptionExpression.class).getOperand(); + PySubscriptionExpression subscription = PsiTreeUtil.getParentOfType(original, PySubscriptionExpression.class); + if (subscription == null) return; + PsiElement operand = subscription.getOperand(); if (operand != null) { PsiReference reference = operand.getReference(); if (reference != null) { diff --git a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java index e85560cb8256..322a19acd8ff 100644 --- a/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStatementEffectInspection.java @@ -5,6 +5,7 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.ResolveResult; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.PyBundle; import com.jetbrains.python.actions.StatementEffectDocstringQuickFix; import com.jetbrains.python.actions.StatementEffectFunctionCallQuickFix; @@ -47,7 +48,7 @@ public class PyStatementEffectInspection extends PyInspection { @Override public void visitPyExpressionStatement(final PyExpressionStatement node) { - if (PydevConsoleRunner.isInPydevConsole(node)) { + if (PydevConsoleRunner.isInPydevConsole(node) || MakoLanguage._isDisabledFor(node)) { return; } final PyExpression expression = node.getExpression(); diff --git a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java index 7e8c1f8dbbda..dd9e765558ee 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnboundLocalVariableInspection.java @@ -15,6 +15,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; import com.jetbrains.cython.CythonLanguageDialect; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.PyBundle; import com.jetbrains.python.actions.AddGlobalQuickFix; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; @@ -50,7 +51,7 @@ public class PyUnboundLocalVariableInspection extends PyInspection { return new PyInspectionVisitor(holder){ @Override public void visitPyReferenceExpression(final PyReferenceExpression node) { - if (CythonLanguageDialect._isDisabledFor(node)) { + if (CythonLanguageDialect._isDisabledFor(node) || MakoLanguage._isDisabledFor(node)) { return; } final Set largeFunctions = session.getUserData(LARGE_FUNCTIONS_KEY); diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 9c8b4cfb4061..6fe98876189f 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -15,6 +15,7 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Consumer; import com.jetbrains.cython.CythonLanguageDialect; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.actions.*; @@ -211,7 +212,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { @Override public void visitPyElement(final PyElement node) { super.visitPyElement(node); - if (CythonLanguageDialect._isDisabledFor(node)) { + if (CythonLanguageDialect._isDisabledFor(node) || MakoLanguage._isDisabledFor(node)) { return; } if (node instanceof PyReferenceOwner) { diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java index efae1775631a..83298fcf4257 100644 --- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java +++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java @@ -27,7 +27,7 @@ public class ExpressionParsing extends Parsing { buildTokenElement(PyElementTypes.TARGET_EXPRESSION, myBuilder); } else { - buildTokenElement(PyElementTypes.REFERENCE_EXPRESSION, myBuilder); + buildTokenElement(getReferenceType(), myBuilder); } return true; } @@ -311,7 +311,7 @@ public class ExpressionParsing extends Parsing { expr.done(PyElementTypes.TARGET_EXPRESSION); } else { - expr.done(PyElementTypes.REFERENCE_EXPRESSION); + expr.done(getReferenceType()); } expr = expr.precede(); } diff --git a/python/src/com/jetbrains/python/parsing/Parsing.java b/python/src/com/jetbrains/python/parsing/Parsing.java index 52a5e5d9e714..1eb7b1a8136f 100644 --- a/python/src/com/jetbrains/python/parsing/Parsing.java +++ b/python/src/com/jetbrains/python/parsing/Parsing.java @@ -3,6 +3,7 @@ package com.jetbrains.python.parsing; import com.intellij.lang.PsiBuilder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.tree.IElementType; +import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.psi.PyElementType; import org.jetbrains.annotations.Nullable; @@ -77,4 +78,8 @@ public class Parsing { builder.advanceLexer(); marker.done(type); } + + protected IElementType getReferenceType() { + return PyElementTypes.REFERENCE_EXPRESSION; + } } diff --git a/python/src/com/jetbrains/python/parsing/StatementParsing.java b/python/src/com/jetbrains/python/parsing/StatementParsing.java index 751b94236ac9..c3a810fcb1a2 100644 --- a/python/src/com/jetbrains/python/parsing/StatementParsing.java +++ b/python/src/com/jetbrains/python/parsing/StatementParsing.java @@ -4,6 +4,7 @@ import com.intellij.lang.ITokenTypeRemapper; import com.intellij.lang.PsiBuilder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.text.CharArrayUtil; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyTokenTypes; @@ -250,7 +251,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } while (builder.getTokenType() == PyTokenTypes.COMMA) { builder.advanceLexer(); - if (PyTokenTypes.END_OF_STATEMENT.contains(builder.getTokenType())) { + if (getEndOfStatementsTokens().contains(builder.getTokenType())) { break; } getExpressionParser().parseSingleExpression(false); @@ -270,7 +271,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { LOG.assertTrue(builder.getTokenType() == PyTokenTypes.RETURN_KEYWORD); final PsiBuilder.Marker returnStatement = builder.mark(); builder.advanceLexer(); - if (builder.getTokenType() != null && !PyTokenTypes.END_OF_STATEMENT.contains(builder.getTokenType())) { + if (builder.getTokenType() != null && !getEndOfStatementsTokens().contains(builder.getTokenType())) { getExpressionParser().parseExpression(); } checkEndOfStatement(inSuite); @@ -286,7 +287,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } while (myBuilder.getTokenType() == PyTokenTypes.COMMA) { myBuilder.advanceLexer(); - if (!PyTokenTypes.END_OF_STATEMENT.contains(myBuilder.getTokenType())) { + if (!getEndOfStatementsTokens().contains(myBuilder.getTokenType())) { if (!getExpressionParser().parseSingleExpression(false)) { myBuilder.error("expression expected"); } @@ -301,7 +302,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { assertCurrentToken(PyTokenTypes.RAISE_KEYWORD); final PsiBuilder.Marker raiseStatement = myBuilder.mark(); myBuilder.advanceLexer(); - if (!PyTokenTypes.END_OF_STATEMENT.contains(myBuilder.getTokenType())) { + if (!getEndOfStatementsTokens().contains(myBuilder.getTokenType())) { getExpressionParser().parseSingleExpression(false); if (myBuilder.getTokenType() == PyTokenTypes.COMMA) { myBuilder.advanceLexer(); @@ -419,7 +420,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } } else { // from X import _ - String token_text = parseIdentifier(PyElementTypes.REFERENCE_EXPRESSION); + String token_text = parseIdentifier(getReferenceType()); if (from_future) { // TODO: mark all known future feature names if (TOK_WITH_STATEMENT.equals(token_text)) { @@ -486,14 +487,14 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } PsiBuilder.Marker marker = myBuilder.mark(); myBuilder.advanceLexer(); - marker.done(PyElementTypes.REFERENCE_EXPRESSION); + marker.done(getReferenceType()); boolean old_expect_AS_kwd = myExpectAsKeyword; myExpectAsKeyword = expect_as; while (myBuilder.getTokenType() == PyTokenTypes.DOT) { marker = marker.precede(); myBuilder.advanceLexer(); checkMatches(PyTokenTypes.IDENTIFIER, "identifier expected"); - marker.done(PyElementTypes.REFERENCE_EXPRESSION); + marker.done(getReferenceType()); } myExpectAsKeyword = old_expect_AS_kwd; return true; @@ -813,6 +814,10 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { return source; } + protected TokenSet getEndOfStatementsTokens() { + return PyTokenTypes.END_OF_STATEMENT; + } + private static boolean isWordAtPosition(CharSequence text, int start, int end, final String tokenText) { return CharArrayUtil.regionMatches(text, start, end, tokenText) && end - start == tokenText.length(); } diff --git a/python/src/com/jetbrains/python/testing/PythonTestRunConfigurationForm.java b/python/src/com/jetbrains/python/testing/PythonTestRunConfigurationForm.java index 500244344093..25bd179f6c77 100644 --- a/python/src/com/jetbrains/python/testing/PythonTestRunConfigurationForm.java +++ b/python/src/com/jetbrains/python/testing/PythonTestRunConfigurationForm.java @@ -202,7 +202,8 @@ public class PythonTestRunConfigurationForm implements AbstractPythonTestRunConf myTestMethodTextField.setVisible(testType == TestType.TEST_METHOD || testType == TestType.TEST_FUNCTION); myPatternTextField.setEnabled(myPatternCheckBox.isSelected()); myParamTextField.setEnabled(myParamCheckBox.isSelected()); - + myTestMethodComponent.getLabel().setText(testType == TestType.TEST_METHOD? PyBundle.message("runcfg.unittest.dlg.method_label") + : PyBundle.message("runcfg.unittest.dlg.function_label")); } public JComponent getPanel() { diff --git a/python/src/com/jetbrains/python/testing/unittest/PythonUnitTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/unittest/PythonUnitTestConfigurationProducer.java index d67a9a682970..7817af98a718 100644 --- a/python/src/com/jetbrains/python/testing/unittest/PythonUnitTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/unittest/PythonUnitTestConfigurationProducer.java @@ -36,6 +36,7 @@ public class PythonUnitTestConfigurationProducer extends PythonTestConfiguration } if (!result.isEmpty()) return true; } + else return true; } return false; } diff --git a/python/src/com/jetbrains/python/validation/DocStringAnnotator.java b/python/src/com/jetbrains/python/validation/DocStringAnnotator.java index 12f6620fd1f2..1757e51f829b 100644 --- a/python/src/com/jetbrains/python/validation/DocStringAnnotator.java +++ b/python/src/com/jetbrains/python/validation/DocStringAnnotator.java @@ -2,6 +2,7 @@ package com.jetbrains.python.validation; import com.intellij.lang.annotation.Annotation; import com.intellij.openapi.util.TextRange; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.PythonDocStringFinder; import com.jetbrains.python.console.PydevConsoleRunner; import com.jetbrains.python.documentation.*; @@ -30,6 +31,9 @@ public class DocStringAnnotator extends PyAnnotator { @Override public void visitPyAssignmentStatement(PyAssignmentStatement node) { + if (MakoLanguage._isDisabledFor(node)) { + return; + } PyExpression left = node.getLeftHandSideExpression(); if (left != null && "__doc__".equals(left.getText())) { PyExpression right = node.getAssignedValue(); @@ -41,6 +45,9 @@ public class DocStringAnnotator extends PyAnnotator { @Override public void visitPyExpressionStatement(PyExpressionStatement node) { + if (MakoLanguage._isDisabledFor(node)) { + return; + } if (node.getExpression() instanceof PyStringLiteralExpression && EpydocUtil.isVariableDocString((PyStringLiteralExpression)node.getExpression())) { annotateDocStringStmt((PyStringLiteralExpression)node.getExpression()); diff --git a/python/src/com/jetbrains/python/validation/ParameterListAnnotator.java b/python/src/com/jetbrains/python/validation/ParameterListAnnotator.java index 9da98d146ffb..5a49dbb0c02f 100644 --- a/python/src/com/jetbrains/python/validation/ParameterListAnnotator.java +++ b/python/src/com/jetbrains/python/validation/ParameterListAnnotator.java @@ -2,6 +2,7 @@ package com.jetbrains.python.validation; import com.intellij.util.containers.HashSet; import com.jetbrains.cython.CythonLanguageDialect; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.PyBundle; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.ParamHelper; @@ -14,6 +15,8 @@ import java.util.Set; public class ParameterListAnnotator extends PyAnnotator { @Override public void visitPyParameterList(final PyParameterList paramlist) { + if (MakoLanguage._isDisabledFor(paramlist)) + return; final LanguageLevel languageLevel = ((PyFile)paramlist.getContainingFile()).getLanguageLevel(); ParamHelper.walkDownParamArray( paramlist.getParameters(), diff --git a/python/src/com/jetbrains/python/validation/ReturnAnnotator.java b/python/src/com/jetbrains/python/validation/ReturnAnnotator.java index 52983821ca33..b287d6f1ffef 100644 --- a/python/src/com/jetbrains/python/validation/ReturnAnnotator.java +++ b/python/src/com/jetbrains/python/validation/ReturnAnnotator.java @@ -1,6 +1,7 @@ package com.jetbrains.python.validation; import com.intellij.psi.util.PsiTreeUtil; +import com.jetbrains.mako.MakoLanguage; import com.jetbrains.python.psi.*; /** @@ -8,6 +9,8 @@ import com.jetbrains.python.psi.*; */ public class ReturnAnnotator extends PyAnnotator { public void visitPyReturnStatement(final PyReturnStatement node) { + if (MakoLanguage._isDisabledFor(node)) + return; PyFunction function = PsiTreeUtil.getParentOfType(node, PyFunction.class, false, PyClass.class); if (function == null) { getHolder().createErrorAnnotation(node, "'return' outside of function");