From 200e67ca65af85a7fe9ef29d240f3c659476983d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 3 Jul 2015 16:00:02 +0300 Subject: [PATCH] IDEA-106141 (trailing annotations excluded from an incomplete reference expression) I.e. in "X. \n @A public T m()", @A is no longer a part of "X.". --- .../lang/java/parser/ExpressionParser.java | 8 +++- .../normal/MethodCallBeforeAnnotation2.java | 7 +++ .../MethodCallBeforeAnnotation2_After.java | 7 +++ .../expressions/AnnotatedRefExpr1.txt | 17 +++---- .../completion/TabCompletionTest.java | 47 +++++++++++++------ 5 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2_After.java diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java index dc919245f5c9..2b8fead86fc4 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java @@ -401,17 +401,21 @@ public class ExpressionParser { expr.done(dotTokenType == JavaTokenType.THIS_KEYWORD ? JavaElementType.THIS_EXPRESSION : JavaElementType.SUPER_EXPRESSION); } else { - dotPos.drop(); PsiBuilder.Marker refExpr = expr.precede(); myParser.getReferenceParser().parseReferenceParameterList(builder, false, false); - if (!expectOrError(builder, ID_OR_SUPER, "expected.identifier")) { + if (!expect(builder, ID_OR_SUPER)) { + dotPos.rollbackTo(); + builder.advanceLexer(); + myParser.getReferenceParser().parseReferenceParameterList(builder, false, false); + error(builder, JavaErrorMessages.message("expected.identifier")); refExpr.done(JavaElementType.REFERENCE_EXPRESSION); startMarker.drop(); return refExpr; } + dotPos.drop(); refExpr.done(JavaElementType.REFERENCE_EXPRESSION); expr = refExpr; } diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2.java new file mode 100644 index 000000000000..ebee75f1f91c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2.java @@ -0,0 +1,7 @@ +class MyClass { + Object o = new Object(); + String s = o. + + @Annotation + String myAnnotatedMethod() { return ""; } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2_After.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2_After.java new file mode 100644 index 000000000000..84884aac1c38 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation2_After.java @@ -0,0 +1,7 @@ +class MyClass { + Object o = new Object(); + String s = o.toString() + + @Annotation + String myAnnotatedMethod() { return ""; } +} diff --git a/java/java-tests/testData/psi/parser-partial/expressions/AnnotatedRefExpr1.txt b/java/java-tests/testData/psi/parser-partial/expressions/AnnotatedRefExpr1.txt index 5320d0351bf7..a727124841a0 100644 --- a/java/java-tests/testData/psi/parser-partial/expressions/AnnotatedRefExpr1.txt +++ b/java/java-tests/testData/psi/parser-partial/expressions/AnnotatedRefExpr1.txt @@ -1,5 +1,5 @@ PsiJavaFile:AnnotatedRefExpr1.java - PsiReferenceExpression:@A C1.@B() + PsiReferenceExpression:@A C1. PsiReferenceExpression:@A C1 PsiReferenceParameterList @@ -14,20 +14,15 @@ PsiJavaFile:AnnotatedRefExpr1.java PsiWhiteSpace(' ') PsiIdentifier:C1('C1') PsiJavaToken:DOT('.') - PsiAnnotation - PsiJavaToken:AT('@') - PsiJavaCodeReferenceElement:B - PsiIdentifier:B('B') - PsiReferenceParameterList - - PsiAnnotationParameterList - PsiJavaToken:LPARENTH('(') - PsiJavaToken:RPARENTH(')') PsiReferenceParameterList PsiErrorElement:Identifier expected - PsiWhiteSpace(' ') PsiErrorElement:Unparsed tokens + PsiJavaToken:AT('@') + PsiIdentifier:B('B') + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiWhiteSpace(' ') PsiJavaToken:LPARENTH('(') PsiJavaToken:RPARENTH(')') \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java index 212ced546d12..2e5669ea9063 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java @@ -1,4 +1,18 @@ - +/* + * Copyright 2000-2015 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.intellij.codeInsight.completion; import com.intellij.JavaTestUtil; @@ -9,38 +23,43 @@ public class TabCompletionTest extends LightFixtureCompletionTestCase { return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/normal"; } - public void testMethodCallCompletionWithTab() throws Exception { + public void testMethodCallCompletionWithTab() { configureByFile("MethodLookup3.java"); checkResultByFile("MethodLookup3_After.java"); } - public void _testMethodCallBeforeAnnotation() { - String name = getTestName(false); - myFixture.configureByFile(name + ".java"); - myFixture.completeBasic(); - myFixture.type("tos\t"); - checkResultByFile(name + "_After.java"); - } - - public void testReplaceThisWithSuper() throws Throwable { + public void testReplaceThisWithSuper() { configureByFile("ReplaceThisWithSuper.java"); checkResultByFile("ReplaceThisWithSuper_After.java"); } - public void testTabInXml() throws Throwable { + public void testTabInXml() { configureByFile("TabInXml.xml"); checkResultByFile("TabInXml_After.xml"); } - public void testTabInXml2() throws Throwable { + public void testTabInXml2() { configureByFile("TabInXml2.xml"); checkResultByFile("TabInXml2_After.xml"); } + public void testMethodCallBeforeAnnotation() { + myFixture.configureByFile("MethodCallBeforeAnnotation.java"); + myFixture.completeBasic(); + myFixture.type("tos\t"); + checkResultByFile("MethodCallBeforeAnnotation_After.java"); + } + + public void testMethodCallBeforeAnnotation2() { + myFixture.configureByFile("MethodCallBeforeAnnotation2.java"); + myFixture.completeBasic(); + myFixture.type("tos\t"); + checkResultByFile("MethodCallBeforeAnnotation2_After.java"); + } + @Override protected void complete() { super.complete(); selectItem(myItems[0], '\t'); } - } \ No newline at end of file