tweak decorator parsing so that following line comment is outside the text range of PyDecorator (PY-5912)

This commit is contained in:
Dmitry Jemerov
2013-11-05 18:37:14 +01:00
parent a61112a8e8
commit f52709b867
6 changed files with 76 additions and 5 deletions

View File

@@ -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);

View File

@@ -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<IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) {
return 0;
}
}

View File

@@ -19,7 +19,7 @@ def f9():
def deco2(p1, p2): pass
<warning descr="Parameter 'p2' unfilled">@deco2 # fail: missing p2</warning>
<warning descr="Parameter 'p2' unfilled">@deco2</warning> # fail: missing p2
def f10():
pass
@@ -61,7 +61,7 @@ class Dec2:
def f17():
pass
<warning descr="Parameter 'p2' unfilled">@Dec2 # fail: no p2</warning>
<warning descr="Parameter 'p2' unfilled">@Dec2</warning> # fail: no p2
def f18():
pass

View File

@@ -0,0 +1,3 @@
@uncallable_deco # some comment
def f():
pass

View File

@@ -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
<empty list>
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')

View File

@@ -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;