diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java index df1ee5cccb10..2d51bced73e7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; +import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.*; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.constructor.ConstructorBody; @@ -36,6 +37,8 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitio import org.jetbrains.plugins.groovy.lang.parser.parsing.toplevel.CompilationUnit; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*; + /** * Parser for Groovy script files * @@ -50,13 +53,13 @@ public class GroovyParser implements PsiParser { @NotNull public ASTNode parse(IElementType root, PsiBuilder builder) { //builder.setDebugMode(true); - if (root == GroovyElementTypes.OPEN_BLOCK) { + if (root == OPEN_BLOCK) { OpenOrClosableBlock.parseOpenBlockDeep(builder, this); } - else if (root == GroovyElementTypes.CLOSABLE_BLOCK) { + else if (root == CLOSABLE_BLOCK) { OpenOrClosableBlock.parseClosableBlockDeep(builder, this); } - else if (root == GroovyElementTypes.CONSTRUCTOR_BODY) { + else if (root == CONSTRUCTOR_BODY) { ConstructorBody.parseConstructorBodyDeep(builder, this); } else { @@ -73,12 +76,12 @@ public class GroovyParser implements PsiParser { ParserUtils.getToken(builder, GroovyTokenTypes.kFOR); if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } if (!ForStatement.forClauseParse(builder, this)) { builder.error(GroovyBundle.message("for.clause.expected")); - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } @@ -88,7 +91,7 @@ public class GroovyParser implements PsiParser { while (!builder.eof() && GroovyTokenTypes.mNLS == builder.getTokenType()){ builder.advanceLexer(); } - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } @@ -99,18 +102,18 @@ public class GroovyParser implements PsiParser { if (parseExtendedStatement(builder)) { warn.rollbackTo(); - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } if (!parseStatement(builder, true)) { warn.rollbackTo(); builder.error(GroovyBundle.message("expression.expected")); - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } else { warn.drop(); - marker.done(GroovyElementTypes.FOR_STATEMENT); + marker.done(FOR_STATEMENT); return true; } } @@ -126,10 +129,8 @@ public class GroovyParser implements PsiParser { } if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { -// ifStmtMarker.done(IF_STATEMENT); -// return IF_STATEMENT; - ifStmtMarker.drop(); - return false; + ifStmtMarker.done(IF_STATEMENT); + return true; } if (!ConditionalExpression.parse(builder, this)) { @@ -150,7 +151,7 @@ public class GroovyParser implements PsiParser { builder.error(GroovyBundle.message("rparen.expected")); } if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN)) { - ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + ifStmtMarker.done(IF_STATEMENT); return true; } } @@ -163,7 +164,7 @@ public class GroovyParser implements PsiParser { if (!parseStatement(builder, true) && !parseExtendedStatement(builder)) { warn.rollbackTo(); builder.error(GroovyBundle.message("expression.expected")); - ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + ifStmtMarker.done(IF_STATEMENT); return true; } else { warn.drop(); @@ -184,18 +185,18 @@ public class GroovyParser implements PsiParser { if (!parseStatement(builder, true) && !parseExtendedStatement(builder)) { warn.rollbackTo(); builder.error(GroovyBundle.message("expression.expected")); - ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + ifStmtMarker.done(IF_STATEMENT); return true; } else { warn.drop(); } - ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + ifStmtMarker.done(IF_STATEMENT); return true; } else { rb.rollbackTo(); - ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + ifStmtMarker.done(IF_STATEMENT); return true; } } @@ -279,7 +280,7 @@ public class GroovyParser implements PsiParser { ParserUtils.getToken(builder, GroovyTokenTypes.kWHILE); if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { - marker.done(GroovyElementTypes.WHILE_STATEMENT); + marker.done(WHILE_STATEMENT); return true; } @@ -295,7 +296,7 @@ public class GroovyParser implements PsiParser { builder.error(GroovyBundle.message("rparen.expected")); } if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN)) { - marker.done(GroovyElementTypes.WHILE_STATEMENT); + marker.done(WHILE_STATEMENT); return true; } } @@ -306,11 +307,11 @@ public class GroovyParser implements PsiParser { if (!parseStatement(builder, true) && !parseExtendedStatement(builder)) { warn.rollbackTo(); builder.error(GroovyBundle.message("expression.expected")); - marker.done(GroovyElementTypes.WHILE_STATEMENT); + marker.done(WHILE_STATEMENT); return true; } else { warn.drop(); - marker.done(GroovyElementTypes.WHILE_STATEMENT); + marker.done(WHILE_STATEMENT); return true; } } @@ -391,7 +392,7 @@ public class GroovyParser implements PsiParser { if (isBlockStatementNeeded && GroovyTokenTypes.mLCURLY.equals(builder.getTokenType())) { final PsiBuilder.Marker marker = builder.mark(); OpenOrClosableBlock.parseOpenBlockDeep(builder, this); - marker.done(GroovyElementTypes.BLOCK_STATEMENT); + marker.done(BLOCK_STATEMENT); return true; } @@ -467,21 +468,39 @@ public class GroovyParser implements PsiParser { //declaration PsiBuilder.Marker declMarker = builder.mark(); - if (!Declaration.parse(builder, false, this)) { - declMarker.rollbackTo(); - } else { - declMarker.drop(); + boolean modifiersParsed = Modifiers.parse(builder, this); + + if (kIMPORT == builder.getTokenType()) { + final PsiBuilder.Marker impMarker = declMarker.precede(); + ImportStatement.parseAfterModifiers(builder); + declMarker.done(IMPORT_STATEMENT); + impMarker.error(GroovyBundle.message("import.not.allowed")); return true; } - PsiBuilder.Marker marker = builder.mark(); - if (ImportStatement.parse(builder, this)) { - marker.error(GroovyBundle.message("import.not.allowed")); + if (kCLASS == builder.getTokenType() || kINTERFACE == builder.getTokenType() || kENUM == builder.getTokenType() || mAT == builder.getTokenType()) { + final IElementType tdType = TypeDefinition.parseAfterModifiers(builder, this); + if (tdType != WRONGWAY) { + declMarker.done(tdType); + return true; + } } - else { - marker.drop(); + + final IElementType declType = Declaration.parseAfterModifiers(builder, false, false, this, declMarker, modifiersParsed); + if (declType != WRONGWAY) { + if (declType != null) { + declMarker.done(declType); + } else { + declMarker.drop(); + } + return true; } - if (TypeDefinition.parse(builder, this)) return true; + + if (modifiersParsed) { + declMarker.done(VARIABLE_DEFINITION_ERROR); + return true; + } + declMarker.rollbackTo(); return AssignmentExpression.parse(builder, this, true); @@ -498,14 +517,14 @@ public class GroovyParser implements PsiParser { private boolean parseLabeledStatement(PsiBuilder builder) { PsiBuilder.Marker marker = builder.mark(); - ParserUtils.eatElement(builder, GroovyElementTypes.LABEL); + ParserUtils.eatElement(builder, LABEL); ParserUtils.getToken(builder, GroovyTokenTypes.mCOLON); ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); parseStatement(builder, false); - marker.done(GroovyElementTypes.LABELED_STATEMENT); + marker.done(LABELED_STATEMENT); return true; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java index 6e014467c0ea..4612dfff1f73 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/declaration/Declaration.java @@ -18,12 +18,12 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration; import com.intellij.lang.PsiBuilder; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement; import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeParameters; import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeSpec; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; @@ -50,11 +50,41 @@ public class Declaration implements GroovyElementTypes { //allows error messages boolean modifiersParsed = Modifiers.parse(builder, parser); + final boolean methodStart = mLT == builder.getTokenType(); + final IElementType type = parseAfterModifiers(builder, isInClass, isInAnnotation, parser, declMarker, modifiersParsed); + if (type == WRONGWAY) { + if (modifiersParsed && methodStart) { + declMarker.error(GroovyBundle.message("method.definitions.expected")); + return false; + } + + declMarker.rollbackTo(); + if (modifiersParsed) { + builder.error(GroovyBundle.message("variable.definitions.expected")); + } + + return false; + } + + if (type != null) { + declMarker.done(type); + } else { + declMarker.drop(); + } + return true; + } + + @Nullable + public static IElementType parseAfterModifiers(PsiBuilder builder, + boolean isInClass, + boolean isInAnnotation, + GroovyParser parser, + PsiBuilder.Marker declMarker, boolean modifiersParsed) { if (modifiersParsed && mLT == builder.getTokenType()) { TypeParameters.parse(builder); PsiBuilder.Marker checkMarker = builder.mark(); //point to begin of type or variable - if (TypeSpec.parse(builder, true) == fail) { //if type wasn't recognized trying parse VaribleDeclaration + if (TypeSpec.parse(builder, true) == fail) { //if type wasn't recognized trying parse VariableDeclaration checkMarker.rollbackTo(); } else { checkMarker.drop(); @@ -62,17 +92,17 @@ public class Declaration implements GroovyElementTypes { IElementType decl = VariableDefinitions.parseDefinitions(builder, isInClass, false, false, true, modifiersParsed, false, parser); if (WRONGWAY.equals(decl)) { - declMarker.error(GroovyBundle.message("method.definitions.expected")); - } else { - declMarker.done(METHOD_DEFINITION); + return WRONGWAY; } - return true; - } else if (modifiersParsed) { + return METHOD_DEFINITION; + } + + if (modifiersParsed) { PsiBuilder.Marker checkMarker = builder.mark(); //point to begin of type or variable - if (TypeSpec.parse(builder, false) == fail) { //if type wasn't recognized trying parse VaribleDeclaration + if (TypeSpec.parse(builder, false) == fail) { //if type wasn't recognized trying parse VariableDeclaration checkMarker.rollbackTo(); if (isInAnnotation) { @@ -83,14 +113,9 @@ public class Declaration implements GroovyElementTypes { IElementType varDecl = VariableDefinitions.parse(builder, isInClass, modifiersParsed, parser); if (WRONGWAY.equals(varDecl)) { - declMarker.rollbackTo(); - builder.error(GroovyBundle.message("variable.definitions.expected")); - return false; - } else { - declMarker.done(varDecl); - return true; + return WRONGWAY; } - + return varDecl; } else { //type was recognized, identifier here //starts after type IElementType varDeclarationTop = VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser); @@ -106,17 +131,13 @@ public class Declaration implements GroovyElementTypes { IElementType varDecl = VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser); if (WRONGWAY.equals(varDecl)) { - builder.error(GroovyBundle.message("variable.definitions.expected")); - declMarker.rollbackTo(); - return false; + return WRONGWAY; } else { - declMarker.done(varDecl); - return true; + return varDecl; } } else { checkMarker.drop(); - declMarker.done(varDeclarationTop); - return true; + return varDeclarationTop; } } } else { @@ -130,8 +151,7 @@ public class Declaration implements GroovyElementTypes { && (Character.isLowerCase((text.charAt(0))) || !Character.isLetter(text.charAt(0))) && (ParserUtils.lookAhead(builder, mIDENT, mIDENT) || ParserUtils.lookAhead(builder, mIDENT, mLPAREN))) { //call expression - declMarker.rollbackTo(); - return false; + return WRONGWAY; } boolean typeParsed = false; @@ -140,22 +160,18 @@ public class Declaration implements GroovyElementTypes { //type specification starts with upper case letter if (!typeParsed) { builder.error(GroovyBundle.message("type.specification.expected")); - declMarker.rollbackTo(); - return false; + return WRONGWAY; } } IElementType varDef = VariableDefinitions.parseDefinitions(builder, isInClass, false, false, false, typeParsed, false, parser); if (varDef != WRONGWAY) { - declMarker.done(varDef); - return true; + return varDef; } else if (isInClass && typeParsed) { - declMarker.drop(); - return typeParsed; + return typeParsed ? null : WRONGWAY; } - declMarker.rollbackTo(); - return false; + return WRONGWAY; } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/imports/ImportStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/imports/ImportStatement.java index df52b6191bc2..09c08f0d5455 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/imports/ImportStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/imports/ImportStatement.java @@ -40,15 +40,18 @@ public class ImportStatement implements GroovyElementTypes { impMarker.rollbackTo(); return false; } + + parseAfterModifiers(builder); + impMarker.done(IMPORT_STATEMENT); + return true; + } + + public static void parseAfterModifiers(PsiBuilder builder) { ParserUtils.getToken(builder, kIMPORT, GroovyBundle.message("import.keyword.expected")); ParserUtils.getToken(builder, kSTATIC); if (!ImportReference.parse(builder)) { builder.error(GroovyBundle.message("import.identifier.expected")); } - impMarker.done(IMPORT_STATEMENT); - - return true; } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java index b3f1e8201465..4009eca64528 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/TypeDefinition.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions; import com.intellij.lang.PsiBuilder; +import com.intellij.psi.tree.IElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.typeDef.AnnotationDefinition; @@ -41,27 +42,34 @@ public class TypeDefinition implements GroovyElementTypes { public static boolean parse(PsiBuilder builder, GroovyParser parser) { PsiBuilder.Marker tdMarker = builder.mark(); Modifiers.parse(builder, parser); + + final IElementType tdType = parseAfterModifiers(builder, parser); + if (tdType == WRONGWAY) { + tdMarker.rollbackTo(); + return false; + } + + tdMarker.done(tdType); + return true; + } + + public static IElementType parseAfterModifiers(PsiBuilder builder, GroovyParser parser) { if (builder.getTokenType() == kCLASS && ClassDefinition.parse(builder, parser)) { - tdMarker.done(CLASS_DEFINITION); - return true; + return CLASS_DEFINITION; } if (builder.getTokenType() == kINTERFACE && InterfaceDefinition.parse(builder, parser)) { - tdMarker.done(INTERFACE_DEFINITION); - return true; + return INTERFACE_DEFINITION; } if (builder.getTokenType() == kENUM && EnumDefinition.parse(builder, parser)) { - tdMarker.done(ENUM_DEFINITION); - return true; + return ENUM_DEFINITION; } if (builder.getTokenType() == mAT && AnnotationDefinition.parse(builder, parser)) { - tdMarker.done(ANNOTATION_DEFINITION); - return true; + return ANNOTATION_DEFINITION; } - tdMarker.rollbackTo(); - return false; + return WRONGWAY; } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index ecbc59ae27d0..7ae68e87a667 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -12,7 +12,6 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.impl.DebugUtil; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; @@ -348,21 +347,5 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { doTest(new GroovyAssignabilityCheckInspection()); } - public void testCodeBlockReparse() throws IOException { - myFixture.configureByText("a.groovy", "foo 'a', {}"); - myFixture.checkHighlighting(true, false, false); - final String psiBefore = DebugUtil.psiToString(myFixture.getFile(), false); - - myFixture.type('\n'); - myFixture.checkHighlighting(true, false, false); - final String psiAfter = DebugUtil.psiToString(myFixture.getFile(), false); - - myFixture.configureByText("a.txt", psiBefore); - myFixture.checkResultByFile(getTestName(false) + "1.txt"); - - myFixture.configureByText("a.txt", psiAfter); - myFixture.checkResultByFile(getTestName(false) + "2.txt"); - } - public void testDuplicatedNamedArgs() {doTest();} } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/GroovyReparseTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/GroovyReparseTest.groovy new file mode 100644 index 000000000000..4c03321128ea --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/GroovyReparseTest.groovy @@ -0,0 +1,102 @@ +package org.jetbrains.plugins.groovy.lang.parser + +import com.intellij.psi.impl.DebugUtil +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.plugins.groovy.util.TestUtils +import com.intellij.psi.PsiDocumentManager + +/** + * @author peter + */ +class GroovyReparseTest extends LightCodeInsightFixtureTestCase { + + @Override + protected String getBasePath() { + return TestUtils.getTestDataPath() + "reparse/"; + } + + void checkReparse(String text, String type) { + myFixture.configureByText("a.groovy", text); + PsiDocumentManager.getInstance(project).commitAllDocuments() + final String psiBefore = DebugUtil.psiToString(myFixture.getFile(), false); + + myFixture.type(type); + PsiDocumentManager.getInstance(project).commitAllDocuments() + final String psiAfter = DebugUtil.psiToString(myFixture.getFile(), false); + + myFixture.configureByText("a.txt", psiBefore); + myFixture.checkResultByFile(getTestName(false) + "_before.txt"); + + myFixture.configureByText("a.txt", psiAfter); + myFixture.checkResultByFile(getTestName(false) + "_after.txt"); + } + + public void testCodeBlockReparse() throws IOException { + checkReparse("foo 'a', {}", '\n') + } + + public void testSwitchCaseIf() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "if " + } + + public void testSwitchCaseDef() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "def " + } + + public void testSwitchCaseFor() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "for " + } + public void testSwitchCaseWhile() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "while " + } + public void testSwitchCaseDo() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "do " + } + public void testSwitchCaseSwitch() throws Exception { + checkReparse """ + def foo() { + switch(x) { + case 2: + return 2 + } + } +""", "switch " + } + + +} diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/errors/err_final.test b/plugins/groovy/testdata/parsing/groovy/expressions/errors/err_final.test index 1478ab26e1b0..bc1f1fa474c1 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/errors/err_final.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/errors/err_final.test @@ -1,8 +1,10 @@ -def final +def final ----- Groovy script - PsiErrorElement:';' or new line expected - PsiElement(def)('def') - PsiWhiteSpace(' ') - PsiElement(final)('final') - PsiWhiteSpace(' ') \ No newline at end of file + Variable definitions + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(final)('final') + PsiErrorElement:Identifier, string literal or '(' expected + \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/generics/err3.test b/plugins/groovy/testdata/parsing/groovy/generics/err3.test index 50a95b57e37e..4ae43d53514a 100644 --- a/plugins/groovy/testdata/parsing/groovy/generics/err3.test +++ b/plugins/groovy/testdata/parsing/groovy/generics/err3.test @@ -27,8 +27,6 @@ Groovy script PsiElement(>)('>') PsiWhiteSpace(' ') PsiElement(identifier)('t') - PsiErrorElement:';', '}' or new line expected - PsiWhiteSpace(' ') PsiElement(=)('=') PsiErrorElement:';', '}' or new line expected diff --git a/plugins/groovy/testdata/parsing/groovy/statements/ifstmt/if2.test b/plugins/groovy/testdata/parsing/groovy/statements/ifstmt/if2.test index 56db031dc728..47616764e63c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/ifstmt/if2.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/ifstmt/if2.test @@ -1,9 +1,10 @@ if expr1 expr2 else expr3 ----- Groovy script - PsiElement(if)('if') - PsiErrorElement:'(' expected - + IF statement + PsiElement(if)('if') + PsiErrorElement:'(' expected + PsiWhiteSpace(' ') PsiErrorElement:';' or new line expected PsiElement(identifier)('expr1') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/tuples/doubleParens.test b/plugins/groovy/testdata/parsing/groovy/statements/tuples/doubleParens.test index 052b5049870f..e58137601344 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/tuples/doubleParens.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/tuples/doubleParens.test @@ -1,9 +1,13 @@ def ((a)) ----- Groovy script + Variable definitions + Modifiers + PsiElement(def)('def') + PsiErrorElement:Identifier expected + + PsiWhiteSpace(' ') PsiErrorElement:';' or new line expected - PsiElement(def)('def') - PsiWhiteSpace(' ') PsiElement(()('(') PsiElement(()('(') PsiElement(identifier)('a') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/tuples/nestedTupleUnsupp.test b/plugins/groovy/testdata/parsing/groovy/statements/tuples/nestedTupleUnsupp.test index 09f1753eefc9..e247f12c97bc 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/tuples/nestedTupleUnsupp.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/tuples/nestedTupleUnsupp.test @@ -1,9 +1,13 @@ def ((a,b),c)=[[1,2],3] ----- Groovy script + Variable definitions + Modifiers + PsiElement(def)('def') + PsiErrorElement:Identifier expected + + PsiWhiteSpace(' ') PsiErrorElement:';' or new line expected - PsiElement(def)('def') - PsiWhiteSpace(' ') PsiElement(()('(') PsiElement(()('(') PsiElement(identifier)('a') diff --git a/plugins/groovy/testdata/highlighting/CodeBlockReparse2.txt b/plugins/groovy/testdata/reparse/CodeBlockReparse_after.txt similarity index 100% rename from plugins/groovy/testdata/highlighting/CodeBlockReparse2.txt rename to plugins/groovy/testdata/reparse/CodeBlockReparse_after.txt diff --git a/plugins/groovy/testdata/highlighting/CodeBlockReparse1.txt b/plugins/groovy/testdata/reparse/CodeBlockReparse_before.txt similarity index 100% rename from plugins/groovy/testdata/highlighting/CodeBlockReparse1.txt rename to plugins/groovy/testdata/reparse/CodeBlockReparse_before.txt diff --git a/plugins/groovy/testdata/reparse/SwitchCaseDef_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseDef_after.txt new file mode 100644 index 000000000000..4ed3979693ce --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseDef_after.txt @@ -0,0 +1,50 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + Variable definitions + Modifiers + PsiElement(def)('def') + PsiErrorElement:Identifier, string literal or '(' expected + + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseDef_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseDef_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseDef_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseDo_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseDo_after.txt new file mode 100644 index 000000000000..93c95749b4d8 --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseDo_after.txt @@ -0,0 +1,47 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + Reference expression + PsiElement(identifier)('do') + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseDo_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseDo_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseDo_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseFor_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseFor_after.txt new file mode 100644 index 000000000000..a6945af333a6 --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseFor_after.txt @@ -0,0 +1,49 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + For statement + PsiElement(for)('for') + PsiErrorElement:'(' expected + + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseFor_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseFor_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseFor_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseIf_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseIf_after.txt new file mode 100644 index 000000000000..c9ad5905add8 --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseIf_after.txt @@ -0,0 +1,49 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + IF statement + PsiElement(if)('if') + PsiErrorElement:'(' expected + + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseIf_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseIf_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseIf_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseSwitch_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseSwitch_after.txt new file mode 100644 index 000000000000..6c231a7f6eba --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseSwitch_after.txt @@ -0,0 +1,49 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + Switch statement + PsiElement(switch)('switch') + PsiErrorElement:'(' expected + + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseSwitch_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseSwitch_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseSwitch_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseWhile_after.txt b/plugins/groovy/testdata/reparse/SwitchCaseWhile_after.txt new file mode 100644 index 000000000000..d9ebb5af09c9 --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseWhile_after.txt @@ -0,0 +1,49 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + WHILE statement + PsiElement(while)('while') + PsiErrorElement:'(' expected + + PsiWhiteSpace(' ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n') diff --git a/plugins/groovy/testdata/reparse/SwitchCaseWhile_before.txt b/plugins/groovy/testdata/reparse/SwitchCaseWhile_before.txt new file mode 100644 index 000000000000..3f84b8c5350c --- /dev/null +++ b/plugins/groovy/testdata/reparse/SwitchCaseWhile_before.txt @@ -0,0 +1,44 @@ +Groovy script + PsiElement(new line)('\n ') + Method + Modifiers + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(identifier)('foo') + PsiElement(()('(') + Parameter list + + PsiElement())(')') + PsiWhiteSpace(' ') + Throw clause + + Open block + PsiElement({)('{') + PsiWhiteSpace('\n ') + Switch statement + PsiElement(switch)('switch') + PsiElement(()('(') + Reference expression + PsiElement(identifier)('x') + PsiElement())(')') + PsiWhiteSpace(' ') + PsiElement({)('{') + PsiWhiteSpace('\n ') + Case section + Case label + PsiElement(case)('case') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(:)(':') + PsiElement(new line)('\n ') + RETURN statement + PsiElement(return)('return') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('2') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n ') + PsiElement(})('}') + PsiElement(new line)('\n')