correct brace structure in case of switch with no matching )

more meaningful code block error recovery
This commit is contained in:
peter
2011-03-21 13:38:09 +01:00
parent 7e13bd6f2c
commit 0a64bd39b9
26 changed files with 452 additions and 193 deletions
@@ -59,7 +59,7 @@ public class GroovyClassNameInsertHandler implements InsertHandler<JavaPsiClassR
boolean parens = shouldInsertParentheses(position, item.getObject());
final PsiClass psiClass = item.getObject();
if (isInVariable(position) || GroovyCompletionContributor.isInClosurePropertyParameters(position)) {
if (isInVariable(position) || GroovyCompletionContributor.isInPossibleClosureParameter(position)) {
Project project = context.getProject();
String qname = psiClass.getQualifiedName();
String shortName = psiClass.getName();
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
public class GroovyCompletionConfidence extends CompletionConfidence {
private static boolean isPossibleClosureParameter(GrReferenceExpression ref) {
return PsiJavaPatterns.psiElement().withParent(GrClosableBlock.class).afterLeaf("{").accepts(ref);
return PsiJavaPatterns.psiElement().withParent(GrClosableBlock.class).afterLeaf("{").accepts(ref) || GroovyCompletionContributor.isInPossibleClosureParameter(ref);
}
@NotNull
@@ -31,8 +31,10 @@ import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.FilterPositionUtil;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -69,7 +71,6 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
import static com.intellij.patterns.PsiJavaPatterns.elementType;
import static com.intellij.util.containers.CollectionFactory.hashMap;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils.*;
import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipWhitespaces;
/**
* @author ilyas
@@ -522,30 +523,52 @@ public class GroovyCompletionContributor extends CompletionContributor {
if (semicolonNeeded(context)) {
context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED + ";");
}
else if (isInClosurePropertyParameters(context.getFile().findElementAt(context.getStartOffset()))) {
else if (isInPossibleClosureParameter(context.getFile().findElementAt(context.getStartOffset()))) {
context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED + "->");
}
}
}
public static boolean isInClosurePropertyParameters(PsiElement position) { //Closure cl={String x, <caret>...
public static boolean isInPossibleClosureParameter(PsiElement position) { //Closure cl={String x, <caret>...
if (position == null) return false;
GrVariableDeclaration declaration = PsiTreeUtil.getParentOfType(position, GrVariableDeclaration.class, false, GrStatement.class);
if (declaration == null) {
if (position.getParent() instanceof PsiErrorElement) position = position.getParent();
PsiElement prev = position.getPrevSibling();
prev = skipWhitespaces(prev, false);
if (prev instanceof PsiErrorElement) {
prev = prev.getPrevSibling();
}
prev = skipWhitespaces(prev, false);
if (prev instanceof GrVariableDeclaration) declaration = (GrVariableDeclaration)prev;
if (position instanceof PsiWhiteSpace || position.getNode().getElementType() == GroovyElementTypes.mNLS) {
position = FilterPositionUtil.searchNonSpaceNonCommentBack(position);
}
if (declaration != null) {
if (!(declaration.getParent() instanceof GrClosableBlock)) return false;
PsiElement prevSibling = skipWhitespaces(declaration.getPrevSibling(), false);
return prevSibling instanceof GrParameterList;
boolean hasCommas = false;
while (position != null) {
PsiElement parent = position.getParent();
if (parent instanceof GrVariable) {
PsiElement prev = FilterPositionUtil.searchNonSpaceNonCommentBack(parent);
hasCommas = prev != null && prev.getNode().getElementType() == GroovyElementTypes.mCOMMA;
}
if (parent instanceof GrClosableBlock) {
PsiElement sibling = position.getPrevSibling();
while (sibling != null) {
if (sibling instanceof GrParameterList) {
return hasCommas;
}
boolean isComma = sibling instanceof LeafPsiElement && GroovyElementTypes.mCOMMA == ((LeafPsiElement)sibling).getElementType();
hasCommas |= isComma;
if (isComma ||
sibling instanceof PsiWhiteSpace ||
sibling instanceof PsiErrorElement ||
sibling instanceof GrVariableDeclaration ||
sibling instanceof GrReferenceExpression && !((GrReferenceExpression)sibling).isQualified()
) {
sibling = sibling.getPrevSibling();
}
else {
return false;
}
}
return false;
}
position = parent;
}
return false;
}
@@ -30,6 +30,10 @@ import org.jetbrains.annotations.NonNls;
*/
public class InstanceOfFilter implements ElementFilter {
public boolean isAcceptable(Object element, PsiElement context) {
return isInfixOperatorPosition(context);
}
public static boolean isInfixOperatorPosition(PsiElement context) {
if (context.getParent() != null &&
context.getParent() instanceof GrReferenceExpression &&
context.getParent().getParent() != null &&
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.filters.ElementFilter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil;
import org.jetbrains.plugins.groovy.lang.completion.filters.exprs.InstanceOfFilter;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -37,8 +38,13 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
*/
public class BuiltInTypeFilter implements ElementFilter {
public boolean isAcceptable(Object element, PsiElement context) {
if (InstanceOfFilter.isInfixOperatorPosition(context)) {
return false;
}
final PsiElement parent = context.getParent();
if (parent == null) return false;
PsiElement previous = PsiImplUtil.realPrevious(parent.getPrevSibling());
if (previous != null && GroovyTokenTypes.mAT.equals(previous.getNode().getElementType())) {
return false;
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
@@ -46,6 +47,9 @@ import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*;
*/
public class GroovyParser implements PsiParser {
public static final TokenSet RCURLY_ONLY = TokenSet.create(mRCURLY);
public static final TokenSet CASE_SECTION_END = TokenSet.create(kCASE, kDEFAULT, mRCURLY);
public boolean parseDeep() {
return false;
}
@@ -202,29 +206,8 @@ public class GroovyParser implements PsiParser {
}
public void parseSwitchCaseList(PsiBuilder builder) {
if (!parseStatement(builder, false) && !parseExtendedStatement(builder)) {
builder.error(GroovyBundle.message("wrong.statement"));
return;
}
while (true) {
while (ParserUtils.getToken(builder, mSEMI)) {}
PsiBuilder.Marker beforeSeparators = builder.mark();
ParserUtils.getToken(builder, mNLS);
if (builder.eof() || builder.getTokenType() == kCASE || builder.getTokenType() == kDEFAULT || builder.getTokenType() == mRCURLY) {
beforeSeparators.rollbackTo();
break;
}
beforeSeparators.drop();
boolean first = true;
if (!parseStatement(builder, false) && !parseExtendedStatement(builder)) {
if (first) {
builder.error("statement expected");
first = false;
}
assert builder.getTokenType() != mLCURLY && builder.getTokenType() != mRCURLY;
builder.advanceLexer();
}
if (parseGenericStatement(builder, CASE_SECTION_END)) {
parseCodeBlock(builder, CASE_SECTION_END);
}
}
@@ -281,76 +264,71 @@ public class GroovyParser implements PsiParser {
}
}
/**
* Rolls marker forward after possible errors
*/
private void cleanAfterError(PsiBuilder builder, boolean rCurlyNeeded) {
int braceLevel = 1;
int i = 0;
PsiBuilder.Marker em = builder.mark();
public void parseBlockBody(PsiBuilder builder) {
skipSeparators(builder);
parseCodeBlock(builder, RCURLY_ONLY);
ParserUtils.getToken(builder, mNLS);
}
private void parseCodeBlock(PsiBuilder builder, TokenSet until) {
while (true) {
if (builder.eof()) {
break;
}
final IElementType type = builder.getTokenType();
if (GroovyTokenTypes.mLCURLY == type) {
braceLevel++;
}
else if (GroovyTokenTypes.mRCURLY == type) {
braceLevel--;
if (braceLevel == 0) {
break;
}
}
else if (braceLevel == 1) {
if (!rCurlyNeeded && (GroovyTokenTypes.mNLS.equals(type) || GroovyTokenTypes.mSEMI.equals(type))) {
break;
}
if (isExtendedSeparator(type)) {
break;
}
}
builder.advanceLexer();
i++;
}
if (i > 0) {
em.error(GroovyBundle.message("separator.or.rcurly.expected"));
} else {
em.drop();
if (builder.eof() || until.contains(builder.getTokenType())) break;
if (!parseGenericStatement(builder, until)) break;
}
}
public void parseBlockBody(PsiBuilder builder) {
private boolean parseGenericStatement(PsiBuilder builder, TokenSet until) {
boolean plainStatement = parseStatement(builder, false);
parseExtendedStatement(builder);
if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) {
Separators.parse(builder);
}
while (parseExtendedStatement(builder)) {
Separators.parse(builder);
}
boolean result = parseStatement(builder, false);
while (result &&
(GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) ||
GroovyTokenTypes.mNLS.equals(builder.getTokenType()) || parseExtendedStatement(builder))) {
Separators.parse(builder);
while (parseExtendedStatement(builder)) {
Separators.parse(builder);
if (plainStatement || parseExtendedStatement(builder)) {
if (parseSeparatorsWithoutLastNls(builder, plainStatement, until)) {
return false;
}
result = parseStatement(builder, false);
if (!isExtendedSeparator(builder.getTokenType())) {
cleanAfterError(builder, false);
} else {
builder.error(GroovyBundle.message("wrong.statement"));
assert builder.getTokenType() != mLCURLY && builder.getTokenType() != mRCURLY;
builder.advanceLexer();
}
return true;
}
private boolean parseSeparatorsWithoutLastNls(PsiBuilder builder, boolean requireSeparator, TokenSet until) {
boolean hasSeparator = false;
while (true) {
while (builder.getTokenType() == mSEMI || isExtendedSeparator(builder.getTokenType())) {
hasSeparator = true;
builder.advanceLexer();
}
if (builder.getTokenType() == mNLS) {
PsiBuilder.Marker beforeNls = builder.mark();
hasSeparator = true;
builder.advanceLexer();
if (builder.eof() || until.contains(builder.getTokenType())) {
beforeNls.rollbackTo();
return true;
}
beforeNls.drop();
} else {
break;
}
}
cleanAfterError(builder, true);
Separators.parse(builder);
while (parseExtendedStatement(builder)) {
Separators.parse(builder);
if (builder.eof() || until.contains(builder.getTokenType())) {
return true;
}
if (requireSeparator && !hasSeparator) {
builder.error(GroovyBundle.message("separator.or.rcurly.expected"));
}
return false;
}
private boolean skipSeparators(PsiBuilder builder) {
boolean hasSeparators = false;
while (builder.getTokenType() == mSEMI || isExtendedSeparator(builder.getTokenType()) || builder.getTokenType() == mNLS) {
hasSeparators = true;
builder.advanceLexer();
}
return hasSeparators;
}
public boolean parseStatement(PsiBuilder builder, boolean isBlockStatementNeeded) {
@@ -372,7 +350,8 @@ public class GroovyParser implements PsiParser {
return parseIfStatement(builder);
}
if (GroovyTokenTypes.kSWITCH.equals(builder.getTokenType())) {
return SwitchStatement.parseSwitch(builder, this);
SwitchStatement.parseSwitch(builder, this);
return true;
}
if (GroovyTokenTypes.kTRY.equals(builder.getTokenType())) {
return TryCatchStatement.parse(builder, this);
@@ -31,13 +31,13 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
*/
public class SwitchStatement implements GroovyElementTypes {
public static boolean parseSwitch(PsiBuilder builder, GroovyParser parser) {
public static void parseSwitch(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
ParserUtils.getToken(builder, kSWITCH);
if (!ParserUtils.getToken(builder, mLPAREN, GroovyBundle.message("lparen.expected"))) {
marker.done(SWITCH_STATEMENT);
return true;
return;
}
if (!StrictContextExpression.parse(builder, parser)) {
builder.error(GroovyBundle.message("expression.expected"));
@@ -45,14 +45,9 @@ public class SwitchStatement implements GroovyElementTypes {
ParserUtils.getToken(builder, mNLS);
if (!ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected"))) {
while (!builder.eof() && !mNLS.equals(builder.getTokenType()) && !mRPAREN.equals(builder.getTokenType())) {
builder.error(GroovyBundle.message("rparen.expected"));
builder.advanceLexer();
}
if (!ParserUtils.getToken(builder, mRPAREN)) {
marker.done(SWITCH_STATEMENT);
return true;
}
builder.error(GroovyBundle.message("rparen.expected"));
marker.done(SWITCH_STATEMENT);
return;
}
PsiBuilder.Marker warn = builder.mark();
ParserUtils.getToken(builder, mNLS);
@@ -61,13 +56,11 @@ public class SwitchStatement implements GroovyElementTypes {
warn.rollbackTo();
builder.error(GroovyBundle.message("case.block.expected"));
marker.done(SWITCH_STATEMENT);
return true;
return;
}
warn.drop();
parseCaseBlock(builder, parser);
marker.done(SWITCH_STATEMENT);
return true;
}
private static void parseCaseBlock(PsiBuilder builder, GroovyParser parser) {
@@ -169,9 +169,8 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
doBasicTest();
}
public void testCompletionInParameterListInClosableBlock() throws Throwable {
doBasicTest();
}
public void testCompletionInParameterListInClosableBlock() throws Throwable { doBasicTest(); }
public void testCompletionInParameterListInClosableBlock3() throws Throwable { doBasicTest(); }
public void testCompletionInParameterListInClosableBlock2() throws Throwable {
myFixture.testCompletionVariants(getTestName(false) + ".groovy", "aDouble");
@@ -81,7 +81,6 @@ public class KeywordCompletionTest extends CompletionTestBase {
public void testVar6() throws Throwable { doTest(); }
public void testVar7() throws Throwable { doTest(); }
public void testVar8() throws Throwable { doTest(); }
public void testVar9() throws Throwable { doTest(); }
public void testWhile55() throws Throwable { doTest(); }
@@ -194,6 +194,7 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
public void testDollar() throws Throwable { doTest(); }
public void testNoArrowClosure() throws Throwable { doTest(); }
public void testNoArrowClosure2() throws Throwable { doTest(); }
public void testPropertyAccessError() throws Throwable {
checkParsing "a[b{}}", """Groovy script
@@ -36,6 +36,7 @@ public abstract class GroovyParsingTestCase extends LightCodeInsightFixtureTestC
protected void checkParsing(String input, String output) {
final PsiFile psiFile = TestUtils.createPseudoPhysicalGroovyFile(getProject(), input);
String psiTree = DebugUtil.psiToString(psiFile, false);
assertEquals(output.trim(), psiTree.trim());
String prefix = input.trim() + "\n-----\n";
assertEquals(prefix + output.trim(), prefix + psiTree.trim());
}
}
@@ -138,5 +138,16 @@ def foo() {
""", "\b"
}
public void testSwitchRParen() {
checkReparse """
def foo() {
switch (word w w)<caret> {
case 2:
def x = (y)
}
}
""", "\b"
}
}
@@ -187,49 +187,10 @@ public class StatementsParsingTest extends GroovyParsingTestCase {
public void testVardef$vardeferrsingle4() throws Throwable { doTest(); }
public void testWith$with1() throws Throwable { doTest(); }
public void testWith$with2() throws Throwable { doTest(); }
public void testAfterAs() throws Throwable { doTest(); }
public void testUnnamedField() throws Throwable { doTest(); }
public void testIfRecovery() throws Throwable {
checkParsing """def test239() {
if (foo() {}
}""",
"""Groovy script
Method
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(identifier)('test239')
PsiElement(()('(')
Parameter list
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Throw clause
<empty list>
Open block
PsiElement({)('{')
PsiWhiteSpace('\\n ')
IF statement
PsiElement(if)('if')
PsiWhiteSpace(' ')
PsiElement(()('(')
Method call
Reference expression
PsiElement(identifier)('foo')
Arguments
PsiElement(()('(')
PsiElement())(')')
PsiWhiteSpace(' ')
Closable block
PsiElement({)('{')
Parameter list
<empty list>
PsiElement(})('}')
PsiErrorElement:')' expected
<empty list>
PsiWhiteSpace('\\n ')
PsiElement(})('}')"""
}
public void testIfRecovery() throws Throwable { doTest(); }
public void testSemicolonsOnDifferentLines() throws Throwable { doTest(); }
}
@@ -0,0 +1,5 @@
def x = {
def a, Doubl<caret>
}
@@ -0,0 +1,5 @@
def x = {
def a, Double<caret>
}
@@ -1,12 +0,0 @@
package a.b.c
import org.*
class A {
def foo() {
switch <caret> (k){
}
}
}
-----
@@ -15,8 +15,12 @@ Groovy script
PsiElement({)('{')
Parameter list
<empty list>
PsiErrorElement:';', '}' or new line expected
PsiElement(@)('@')
PsiElement(wrong token)('#')
PsiErrorElement:Wrong statement
<empty list>
PsiElement(@)('@')
PsiErrorElement:Wrong statement
<empty list>
PsiElement(wrong token)('#')
Literal
PsiElement(Integer)('2')
PsiElement(})('}')
@@ -0,0 +1,42 @@
{ a, b, c
println a+b+c
}
-----
Groovy script
Closable block
PsiElement({)('{')
PsiWhiteSpace(' ')
Parameter list
<empty list>
Reference expression
PsiElement(identifier)('a')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiElement(,)(',')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('b')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiElement(,)(',')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('c')
PsiElement(new line)('\n ')
Call expression
Reference expression
PsiElement(identifier)('println')
PsiWhiteSpace(' ')
Command arguments
Additive expression
Additive expression
Reference expression
PsiElement(identifier)('a')
PsiElement(+)('+')
Reference expression
PsiElement(identifier)('b')
PsiElement(+)('+')
Reference expression
PsiElement(identifier)('c')
PsiElement(new line)('\n')
PsiElement(})('}')
@@ -28,8 +28,10 @@ Groovy script
Command arguments
Literal
PsiElement(Gstring)('"bugaga"')
PsiWhiteSpace(' ')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('3')
PsiElement(})('}')
PsiElement(Gstring content)(' ved')
@@ -0,0 +1,40 @@
def test239() {
if (foo() {}
}
-----
Groovy script
Method
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(identifier)('test239')
PsiElement(()('(')
Parameter list
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Throw clause
<empty list>
Open block
PsiElement({)('{')
PsiWhiteSpace('\n ')
IF statement
PsiElement(if)('if')
PsiWhiteSpace(' ')
PsiElement(()('(')
Method call
Reference expression
PsiElement(identifier)('foo')
Arguments
PsiElement(()('(')
PsiElement())(')')
PsiWhiteSpace(' ')
Closable block
PsiElement({)('{')
Parameter list
<empty list>
PsiElement(})('}')
PsiErrorElement:')' expected
<empty list>
PsiWhiteSpace('\n')
PsiElement(})('}')
@@ -0,0 +1,31 @@
def foo() {
;
;;
;
}
-----
Groovy script
Method
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(identifier)('foo')
PsiElement(()('(')
Parameter list
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Throw clause
<empty list>
Open block
PsiElement({)('{')
PsiWhiteSpace('\n ')
PsiElement(;)(';')
PsiElement(new line)('\n ')
PsiElement(;)(';')
PsiElement(;)(';')
PsiElement(new line)('\n\n ')
PsiElement(;)(';')
PsiElement(new line)('\n')
PsiElement(})('}')
@@ -28,9 +28,13 @@ Groovy script
Reference expression
PsiElement(identifier)('e1')
PsiErrorElement:';', '}' or new line expected
PsiElement())(')')
PsiWhiteSpace(' ')
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Closable block
PsiElement({)('{')
Parameter list
<empty list>
PsiElement(})('}')
PsiElement(new line)('\n')
PsiErrorElement:'catch' without 'try'
@@ -49,9 +53,13 @@ Groovy script
Reference expression
PsiElement(identifier)('e2')
PsiErrorElement:';', '}' or new line expected
PsiElement())(')')
PsiWhiteSpace(' ')
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Closable block
PsiElement({)('{')
Parameter list
<empty list>
PsiElement(})('}')
PsiElement(new line)('\n')
PsiErrorElement:'finally' without 'try'
@@ -86,16 +86,28 @@ Groovy script
PsiWhiteSpace('\n ')
PsiElement(identifier)('simplePlugins')
PsiErrorElement:';', '}' or new line expected
PsiElement(.)('.')
PsiElement(identifier)('each')
<empty list>
PsiElement(.)('.')
Method call
Reference expression
PsiElement(identifier)('each')
PsiWhiteSpace(' ')
PsiElement({)('{')
PsiWhiteSpace('\n ')
PsiElement(identifier)('layoutPlugin')
PsiWhiteSpace(' ')
PsiElement(identifier)('it')
PsiElement(new line)('\n ')
PsiElement(})('}')
Arguments
<empty list>
Closable block
PsiElement({)('{')
PsiWhiteSpace('\n ')
Parameter list
<empty list>
Call expression
Reference expression
PsiElement(identifier)('layoutPlugin')
PsiWhiteSpace(' ')
Command arguments
Reference expression
PsiElement(identifier)('it')
PsiElement(new line)('\n ')
PsiElement(})('}')
PsiWhiteSpace('\n\n')
PsiElement(})('}')
PsiElement(new line)('\n')
+2
View File
@@ -79,6 +79,8 @@ Groovy script
PsiElement(new line)('\n ')
Reference expression
PsiElement(identifier)('do')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiWhiteSpace(' ')
RETURN statement
PsiElement(return)('return')
+5 -1
View File
@@ -112,12 +112,16 @@ Groovy script
PsiElement(.)('.')
PsiElement(new line)('\n ')
PsiElement(case)('case')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('3')
PsiErrorElement:statement expected
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiElement(:)(':')
PsiErrorElement:Wrong statement
<empty list>
PsiElement(new line)('\n ')
RETURN statement
PsiElement(return)('return')
+139
View File
@@ -0,0 +1,139 @@
Groovy script
PsiElement(new line)('\n')
Method
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(identifier)('foo')
PsiElement(()('(')
Parameter list
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Throw clause
<empty list>
Open block
PsiElement({)('{')
PsiWhiteSpace('\n ')
Switch statement
PsiElement(switch)('switch')
PsiWhiteSpace(' ')
PsiElement(()('(')
Reference expression
PsiElement(identifier)('word')
PsiErrorElement:')' expected
<empty list>
PsiWhiteSpace(' ')
Call expression
Reference expression
PsiElement(identifier)('w')
PsiWhiteSpace(' ')
Command arguments
Reference expression
PsiElement(identifier)('w')
PsiErrorElement:';', '}' or new line expected
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Closable block
PsiElement({)('{')
PsiWhiteSpace('\n ')
Parameter list
<empty list>
PsiErrorElement:'case' outside 'switch' block
Case label
PsiElement(case)('case')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('2')
PsiElement(:)(':')
PsiElement(new line)('\n ')
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('x')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Parenthesized expression
PsiElement(()('(')
Reference expression
PsiElement(identifier)('y')
PsiElement())(')')
PsiElement(new line)('\n ')
PsiElement(})('}')
PsiElement(new line)('\n ')
PsiElement(})('}')
PsiElement(new line)('\n')
---
Groovy script
PsiElement(new line)('\n')
Method
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(identifier)('foo')
PsiElement(()('(')
Parameter list
<empty list>
PsiElement())(')')
PsiWhiteSpace(' ')
Throw clause
<empty list>
Open block
PsiElement({)('{')
PsiWhiteSpace('\n ')
Switch statement
PsiElement(switch)('switch')
PsiWhiteSpace(' ')
PsiElement(()('(')
Reference expression
PsiElement(identifier)('word')
PsiErrorElement:')' expected
<empty list>
PsiWhiteSpace(' ')
Call expression
Reference expression
PsiElement(identifier)('w')
PsiWhiteSpace(' ')
Command arguments
Method call
Reference expression
PsiElement(identifier)('w')
PsiWhiteSpace(' ')
Arguments
<empty list>
Closable block
PsiElement({)('{')
PsiWhiteSpace('\n ')
Parameter list
<empty list>
PsiErrorElement:'case' outside 'switch' block
Case label
PsiElement(case)('case')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('2')
PsiElement(:)(':')
PsiElement(new line)('\n ')
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('x')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Parenthesized expression
PsiElement(()('(')
Reference expression
PsiElement(identifier)('y')
PsiElement())(')')
PsiElement(new line)('\n ')
PsiElement(})('}')
PsiWhiteSpace('\n ')
PsiElement(})('}')
PsiElement(new line)('\n')