groovy for-in parser fix
[fedora-idea.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / lang / parser / parsing / statements / ForStatement.java
blob6dd9f25bd03b70c719b4d6165c94af3b9ecb4b7f
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.jetbrains.plugins.groovy.lang.parser.parsing.statements;
19 import com.intellij.lang.PsiBuilder;
20 import org.jetbrains.plugins.groovy.GroovyBundle;
21 import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
22 import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
23 import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
24 import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers;
25 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration;
26 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.StrictContextExpression;
27 import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.ShiftExpression;
28 import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeSpec;
29 import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
31 /**
32 * @autor: ilyas
34 public class ForStatement implements GroovyElementTypes {
36 public static boolean forClauseParse(PsiBuilder builder, GroovyParser parser) {
37 ParserUtils.getToken(builder, mNLS);
38 return forInClauseParse(builder, parser) || tradForClauseParse(builder, parser);
41 private static boolean tradForClauseParse(PsiBuilder builder, GroovyParser parser) {
42 PsiBuilder.Marker marker = builder.mark();
44 if (ParserUtils.getToken(builder, mSEMI) || (Declaration.parse(builder, false, parser) && ParserUtils.getToken(builder, mSEMI))) {
45 StrictContextExpression.parse(builder, parser);
46 ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
47 ParserUtils.getToken(builder, mNLS);
48 if (!mRPAREN.equals(builder.getTokenType())) {
49 controlExpressionListParse(builder, parser);
52 else {
53 marker.rollbackTo();
54 marker = builder.mark();
55 controlExpressionListParse(builder, parser);
56 ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
57 StrictContextExpression.parse(builder, parser);
58 ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected"));
59 ParserUtils.getToken(builder, mNLS);
60 if (!mRPAREN.equals(builder.getTokenType())) {
61 controlExpressionListParse(builder, parser);
65 marker.done(FOR_TRADITIONAL_CLAUSE);
66 return true;
70 * Parses list of control expression in for condition
72 private static void controlExpressionListParse(PsiBuilder builder, GroovyParser parser) {
74 if (!StrictContextExpression.parse(builder, parser)) return;
76 while (mCOMMA.equals(builder.getTokenType())) {
78 if (ParserUtils.lookAhead(builder, mCOMMA, mNLS, mRPAREN) || ParserUtils.lookAhead(builder, mCOMMA, mRPAREN)) {
79 ParserUtils.getToken(builder, mCOMMA);
80 builder.error(GroovyBundle.message("expression.expected"));
82 else {
83 ParserUtils.getToken(builder, mCOMMA);
85 ParserUtils.getToken(builder, mNLS);
86 if (!StrictContextExpression.parse(builder, parser)) {
87 ParserUtils.getToken(builder, mNLS);
88 if (!mRPAREN.equals(builder.getTokenType()) && !mSEMI.equals(builder.getTokenType())) {
89 builder.error(GroovyBundle.message("expression.expected"));
91 if (!mRPAREN.equals(builder.getTokenType()) &&
92 !mSEMI.equals(builder.getTokenType()) &&
93 !mCOMMA.equals(builder.getTokenType()) &&
94 !mNLS.equals(builder.getTokenType())) {
95 builder.advanceLexer();
102 * Parses Groovy-style 'in' clause
104 private static boolean forInClauseParse(PsiBuilder builder, GroovyParser parser) {
105 PsiBuilder.Marker marker = builder.mark();
107 PsiBuilder.Marker paramMarker = builder.mark();
109 Modifiers.parse(builder, parser);
111 boolean isBuiltInType = TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType());
113 PsiBuilder.Marker typeSpec = builder.mark();
114 TypeSpec.parseStrict(builder);
116 if (builder.getTokenType() == mIDENT || isBuiltInType) {
117 typeSpec.drop();
119 else {
120 typeSpec.rollbackTo();
123 if (TokenSets.FOR_IN_DELIMITERS.contains(builder.getTokenType())) {
124 builder.error(GroovyBundle.message("identifier.expected"));
125 paramMarker.drop();
127 else if (builder.getTokenType() == mIDENT) {
128 ParserUtils.getToken(builder, mIDENT);
129 paramMarker.done(PARAMETER);
131 else {
132 paramMarker.drop();
133 marker.rollbackTo();
134 return false;
137 if (!ParserUtils.getToken(builder, kIN) && !ParserUtils.getToken(builder, mCOLON)) {
138 marker.rollbackTo();
139 return false;
142 if (!ShiftExpression.parse(builder, parser)) {
143 builder.error(GroovyBundle.message("expression.expected"));
145 marker.done(FOR_IN_CLAUSE);
146 return true;