diff --git a/python/src/com/jetbrains/python/parsing/FunctionParsing.java b/python/src/com/jetbrains/python/parsing/FunctionParsing.java index f9fe799405f1..65709882d37c 100644 --- a/python/src/com/jetbrains/python/parsing/FunctionParsing.java +++ b/python/src/com/jetbrains/python/parsing/FunctionParsing.java @@ -85,10 +85,18 @@ public class FunctionParsing extends Parsing { getExpressionParser().parseArgumentList(); } else { // empty arglist node, so we always have it - myBuilder.mark().done(PyElementTypes.ARGUMENT_LIST); + PsiBuilder.Marker argListMarker = myBuilder.mark(); + argListMarker.setCustomEdgeTokenBinders(LeftBiasedWhitespaceBinder.INSTANCE, null); + argListMarker.done(PyElementTypes.ARGUMENT_LIST); + } + if (atToken(PyTokenTypes.STATEMENT_BREAK)) { + decoratorMarker.done(PyElementTypes.DECORATOR_CALL); + nextToken(); + } + else { + myBuilder.error(message("PARSE.expected.statement.break")); + decoratorMarker.done(PyElementTypes.DECORATOR_CALL); } - checkMatches(PyTokenTypes.STATEMENT_BREAK, message("PARSE.expected.statement.break")); - decoratorMarker.done(PyElementTypes.DECORATOR_CALL); decorated = true; } if (decorated) decoListMarker.done(PyElementTypes.DECORATOR_LIST); diff --git a/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java b/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java new file mode 100644 index 000000000000..38bd0794f487 --- /dev/null +++ b/python/src/com/jetbrains/python/parsing/LeftBiasedWhitespaceBinder.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.parsing; + +import com.intellij.lang.WhitespacesAndCommentsBinder; +import com.intellij.psi.tree.IElementType; + +import java.util.List; + +/** + * @author yole + */ +public class LeftBiasedWhitespaceBinder implements WhitespacesAndCommentsBinder { + public static LeftBiasedWhitespaceBinder INSTANCE = new LeftBiasedWhitespaceBinder(); + + @Override + public int getEdgePosition(List tokens, boolean atStreamEdge, TokenTextGetter getter) { + return 0; + } +} diff --git a/python/testData/inspections/PyArgumentListInspection/decorators.py b/python/testData/inspections/PyArgumentListInspection/decorators.py index 83b09550f065..9377b5eb8148 100644 --- a/python/testData/inspections/PyArgumentListInspection/decorators.py +++ b/python/testData/inspections/PyArgumentListInspection/decorators.py @@ -19,7 +19,7 @@ def f9(): def deco2(p1, p2): pass -@deco2 # fail: missing p2 +@deco2 # fail: missing p2 def f10(): pass @@ -61,7 +61,7 @@ class Dec2: def f17(): pass -@Dec2 # fail: no p2 +@Dec2 # fail: no p2 def f18(): pass diff --git a/python/testData/psi/CommentAfterDecorator.py b/python/testData/psi/CommentAfterDecorator.py new file mode 100644 index 000000000000..bd2fefcf3b2c --- /dev/null +++ b/python/testData/psi/CommentAfterDecorator.py @@ -0,0 +1,3 @@ +@uncallable_deco # some comment +def f(): + pass diff --git a/python/testData/psi/CommentAfterDecorator.txt b/python/testData/psi/CommentAfterDecorator.txt new file mode 100644 index 000000000000..6e8214f79dda --- /dev/null +++ b/python/testData/psi/CommentAfterDecorator.txt @@ -0,0 +1,23 @@ +PyFile:CommentAfterDecorator.py + PyFunction('f') + PyDecoratorList + PyDecorator: @uncallable_deco + PsiElement(Py:AT)('@') + PyReferenceExpression: uncallable_deco + PsiElement(Py:IDENTIFIER)('uncallable_deco') + PyArgumentList + + PsiWhiteSpace(' ') + PsiComment(Py:END_OF_LINE_COMMENT)('# some comment') + PsiWhiteSpace('\n') + PsiElement(Py:DEF_KEYWORD)('def') + PsiWhiteSpace(' ') + PsiElement(Py:IDENTIFIER)('f') + PyParameterList + PsiElement(Py:LPAR)('(') + PsiElement(Py:RPAR)(')') + PsiElement(Py:COLON)(':') + PsiWhiteSpace('\n ') + PyStatementList + PyPassStatement + PsiElement(Py:PASS_KEYWORD)('pass') \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonParsingTest.java b/python/testSrc/com/jetbrains/python/PythonParsingTest.java index 87f9e535ade2..4dcef353c7f1 100644 --- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java @@ -402,6 +402,10 @@ public class PythonParsingTest extends ParsingTestCase { doTest(); } + public void testCommentAfterDecorator() { // PY-5912 + doTest(); + } + public void doTest(LanguageLevel languageLevel) { LanguageLevel prev = myLanguageLevel; myLanguageLevel = languageLevel;