001    /*
002     * Copyright 2010-2014 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.parsing;
018    
019    import com.google.common.collect.ImmutableMap;
020    import com.intellij.lang.PsiBuilder;
021    import com.intellij.psi.tree.IElementType;
022    import com.intellij.psi.tree.TokenSet;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.jet.JetNodeType;
025    import org.jetbrains.jet.lexer.JetToken;
026    import org.jetbrains.jet.lexer.JetTokens;
027    
028    import java.util.Arrays;
029    import java.util.HashSet;
030    import java.util.Set;
031    
032    import static org.jetbrains.jet.JetNodeTypes.*;
033    import static org.jetbrains.jet.lang.parsing.JetParsing.AnnotationParsingMode.REGULAR_ANNOTATIONS_ALLOW_SHORTS;
034    import static org.jetbrains.jet.lang.parsing.JetParsing.AnnotationParsingMode.REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS;
035    import static org.jetbrains.jet.lexer.JetTokens.*;
036    
037    public class JetExpressionParsing extends AbstractJetParsing {
038        private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD);
039        private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT);
040    
041    
042        private static final ImmutableMap<String, JetToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS);
043    
044        private static ImmutableMap<String, JetToken> tokenSetToMap(TokenSet tokens) {
045            ImmutableMap.Builder<String, JetToken> builder = ImmutableMap.builder();
046            for (IElementType token : tokens.getTypes()) {
047                builder.put(token.toString(), (JetToken) token);
048            }
049            return builder.build();
050        }
051    
052        private static final TokenSet TYPE_ARGUMENT_LIST_STOPPERS = TokenSet.create(
053                INTEGER_LITERAL, FLOAT_LITERAL, CHARACTER_LITERAL, OPEN_QUOTE,
054                PACKAGE_KEYWORD, AS_KEYWORD, TYPE_ALIAS_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD, THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD,
055                FUN_KEYWORD, FOR_KEYWORD, NULL_KEYWORD,
056                TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD,
057                CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD,
058                WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL,
059                //            MUL,
060                PLUS, MINUS, EXCL, DIV, PERC, LTEQ,
061                // TODO GTEQ,   foo<bar, baz>=x
062                EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS,
063                SEMICOLON, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, NOT_IN, NOT_IS,
064                COLONCOLON,
065                COLON
066        );
067    
068        /*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.create(
069                // Prefix
070                MINUS, PLUS, MINUSMINUS, PLUSPLUS,
071                EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here
072                LBRACKET, LABEL_IDENTIFIER,
073                // Atomic
074    
075                COLONCOLON, // callable reference
076    
077                LPAR, // parenthesized
078                HASH, // Tuple
079    
080                // literal constant
081                TRUE_KEYWORD, FALSE_KEYWORD,
082                OPEN_QUOTE,
083                INTEGER_LITERAL, CHARACTER_LITERAL, FLOAT_LITERAL,
084                NULL_KEYWORD,
085    
086                LBRACE, // functionLiteral
087    
088                LPAR, // tuple
089    
090                THIS_KEYWORD, // this
091                SUPER_KEYWORD, // super
092    
093                IF_KEYWORD, // if
094                WHEN_KEYWORD, // when
095                TRY_KEYWORD, // try
096                OBJECT_KEYWORD, // object
097    
098                // jump
099                THROW_KEYWORD,
100                RETURN_KEYWORD,
101                CONTINUE_KEYWORD,
102                BREAK_KEYWORD,
103    
104                // loop
105                FOR_KEYWORD,
106                WHILE_KEYWORD,
107                DO_KEYWORD,
108    
109                IDENTIFIER, // SimpleName
110                FIELD_IDENTIFIER, // Field reference
111    
112                PACKAGE_KEYWORD // for absolute qualified names
113        );
114    
115        private static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
116                EXPRESSION_FIRST,
117                TokenSet.create(
118                        // declaration
119                        LBRACKET, // annotation
120                        FUN_KEYWORD,
121                        VAL_KEYWORD, VAR_KEYWORD,
122                        TRAIT_KEYWORD,
123                        CLASS_KEYWORD,
124                        TYPE_ALIAS_KEYWORD
125                ),
126                MODIFIER_KEYWORDS
127        );
128    
129        private static final TokenSet STATEMENT_NEW_LINE_QUICK_RECOVERY_SET =
130                TokenSet.orSet(
131                        TokenSet.andSet(STATEMENT_FIRST, TokenSet.andNot(KEYWORDS, TokenSet.create(IN_KEYWORD))),
132                        TokenSet.create(EOL_OR_SEMICOLON));
133    
134        /*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create(
135                SEMICOLON, ARROW, COMMA, RBRACE, RPAR, RBRACKET
136        );
137    
138        @SuppressWarnings({"UnusedDeclaration"})
139        public enum Precedence {
140            POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL,
141                    DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess
142    
143            PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL, LABEL_IDENTIFIER) { // annotations
144    
145                @Override
146                public void parseHigherPrecedence(JetExpressionParsing parser) {
147                    throw new IllegalStateException("Don't call this method");
148                }
149            },
150    
151            COLON_AS(COLON, AS_KEYWORD, AS_SAFE) {
152                @Override
153                public JetNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
154                    parser.myJetParsing.parseTypeRef();
155                    return BINARY_WITH_TYPE;
156                }
157    
158                @Override
159                public void parseHigherPrecedence(JetExpressionParsing parser) {
160                    parser.parsePrefixExpression();
161                }
162            },
163    
164            MULTIPLICATIVE(MUL, DIV, PERC),
165            ADDITIVE(PLUS, MINUS),
166            RANGE(JetTokens.RANGE),
167            SIMPLE_NAME(IDENTIFIER),
168            ELVIS(JetTokens.ELVIS),
169            IN_OR_IS(IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS) {
170                @Override
171                public JetNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
172                    if (operation == IS_KEYWORD || operation == NOT_IS) {
173                        parser.myJetParsing.parseTypeRef();
174                        return IS_EXPRESSION;
175                    }
176    
177                    return super.parseRightHandSide(operation, parser);
178                }
179            },
180            COMPARISON(LT, GT, LTEQ, GTEQ),
181            EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ),
182            CONJUNCTION(ANDAND),
183            DISJUNCTION(OROR),
184            //        ARROW(JetTokens.ARROW),
185            ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
186            ;
187    
188            static {
189                Precedence[] values = Precedence.values();
190                for (Precedence precedence : values) {
191                    int ordinal = precedence.ordinal();
192                    precedence.higher = ordinal > 0 ? values[ordinal - 1] : null;
193                }
194            }
195    
196            private Precedence higher;
197            private final TokenSet operations;
198    
199            Precedence(IElementType... operations) {
200                this.operations = TokenSet.create(operations);
201            }
202    
203            public void parseHigherPrecedence(JetExpressionParsing parser) {
204                assert higher != null;
205                parser.parseBinaryExpression(higher);
206            }
207    
208            /**
209             *
210             * @param operation the operation sign (e.g. PLUS or IS)
211             * @param parser the parser object
212             * @return node type of the result
213             */
214            public JetNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
215                parseHigherPrecedence(parser);
216                return BINARY_EXPRESSION;
217            }
218    
219            @NotNull
220            public final TokenSet getOperations() {
221                return operations;
222            }
223        }
224    
225        public static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create(
226                DOT, SAFE_ACCESS,
227                COLON, AS_KEYWORD, AS_SAFE,
228                ELVIS,
229                // Can't allow `is` and `!is` because of when entry conditions: IS_KEYWORD, NOT_IS,
230                ANDAND,
231                OROR
232        );
233    
234        public static final TokenSet ALL_OPERATIONS;
235    
236        static {
237            Set<IElementType> operations = new HashSet<IElementType>();
238            Precedence[] values = Precedence.values();
239            for (Precedence precedence : values) {
240                operations.addAll(Arrays.asList(precedence.getOperations().getTypes()));
241            }
242            ALL_OPERATIONS = TokenSet.create(operations.toArray(new IElementType[operations.size()]));
243        }
244    
245        static {
246            IElementType[] operations = OPERATIONS.getTypes();
247            Set<IElementType> opSet = new HashSet<IElementType>(Arrays.asList(operations));
248            IElementType[] usedOperations = ALL_OPERATIONS.getTypes();
249            Set<IElementType> usedSet = new HashSet<IElementType>(Arrays.asList(usedOperations));
250    
251            if (opSet.size() > usedSet.size()) {
252                opSet.removeAll(usedSet);
253                assert false : opSet;
254            }
255            assert usedSet.size() == opSet.size() : "Either some ops are unused, or something a non-op is used";
256    
257            usedSet.removeAll(opSet);
258    
259            assert usedSet.isEmpty() : usedSet.toString();
260        }
261    
262    
263        private final JetParsing myJetParsing;
264    
265        public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
266            super(builder);
267            myJetParsing = jetParsing;
268        }
269    
270        /*
271         * element
272         *   : annotations element
273         *   : "(" element ")" // see tupleLiteral
274         *   : literalConstant
275         *   : functionLiteral
276         *   : tupleLiteral
277         *   : "null"
278         *   : "this" ("<" type ">")?
279         *   : expressionWithPrecedences
280         *   : if
281         *   : try
282         *   : "typeof" "(" element ")"
283         *   : "new" constructorInvocation
284         *   : objectLiteral
285         *   : declaration
286         *   : jump
287         *   : loop
288         *   // block is syntactically equivalent to a functionLiteral with no parameters
289         *   ;
290         */
291        public void parseExpression() {
292            if (!atSet(EXPRESSION_FIRST)) {
293                error("Expecting an expression");
294                return;
295            }
296            parseBinaryExpression(Precedence.ASSIGNMENT);
297        }
298    
299        /*
300         * element (operation element)*
301         *
302         * see the precedence table
303         */
304        private void parseBinaryExpression(Precedence precedence) {
305            //        System.out.println(precedence.name() + " at " + myBuilder.getTokenText());
306    
307            PsiBuilder.Marker expression = mark();
308    
309            precedence.parseHigherPrecedence(this);
310    
311            while (!interruptedWithNewLine() && atSet(precedence.getOperations())) {
312                IElementType operation = tt();
313    
314                parseOperationReference();
315    
316                JetNodeType resultType = precedence.parseRightHandSide(operation, this);
317                expression.done(resultType);
318                expression = expression.precede();
319            }
320    
321            expression.drop();
322        }
323    
324        /*
325         * label prefixExpression
326         */
327        private void parseLabeledExpression() {
328            assert _at(LABEL_IDENTIFIER);
329            PsiBuilder.Marker expression = mark();
330            parseLabel();
331            parsePrefixExpression();
332            expression.done(LABELED_EXPRESSION);
333        }
334    
335        /*
336         * operation? prefixExpression
337         */
338        private void parsePrefixExpression() {
339            //        System.out.println("pre at "  + myBuilder.getTokenText());
340    
341            if (at(LBRACKET)) {
342                if (!parseLocalDeclaration()) {
343                    PsiBuilder.Marker expression = mark();
344                    myJetParsing.parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
345                    parsePrefixExpression();
346                    expression.done(ANNOTATED_EXPRESSION);
347                }
348            }
349            else {
350                myBuilder.disableJoiningComplexTokens();
351                if (at(LABEL_IDENTIFIER)) {
352                    myBuilder.restoreJoiningComplexTokensState();
353                    parseLabeledExpression();
354                }
355                else if (atSet(Precedence.PREFIX.getOperations())) {
356                    PsiBuilder.Marker expression = mark();
357    
358                    parseOperationReference();
359    
360                    myBuilder.restoreJoiningComplexTokensState();
361    
362                    parsePrefixExpression();
363                    expression.done(PREFIX_EXPRESSION);
364                }
365                else {
366                    myBuilder.restoreJoiningComplexTokensState();
367                    parsePostfixExpression();
368                }
369            }
370        }
371    
372        /*
373         * callableReference
374         *   : (userType "?"*)? "::" SimpleName
375         *   ;
376         */
377        private boolean parseCallableReferenceExpression() {
378            PsiBuilder.Marker expression = mark();
379    
380            if (!at(COLONCOLON)) {
381                PsiBuilder.Marker typeReference = mark();
382                myJetParsing.parseUserType();
383                typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
384                typeReference.done(TYPE_REFERENCE);
385    
386                if (!at(COLONCOLON)) {
387                    expression.rollbackTo();
388                    return false;
389                }
390            }
391    
392            advance(); // COLONCOLON
393    
394            parseSimpleNameExpression();
395            expression.done(CALLABLE_REFERENCE_EXPRESSION);
396    
397            return true;
398        }
399    
400        /*
401         * postfixUnaryExpression
402         *   : atomicExpression postfixUnaryOperation*
403         *   : callableReference postfixUnaryOperation*
404         *   ;
405         *
406         * postfixUnaryOperation
407         *   : "++" : "--" : "!!"
408         *   : typeArguments? valueArguments (getEntryPoint? functionLiteral)
409         *   : typeArguments (getEntryPoint? functionLiteral)
410         *   : arrayAccess
411         *   : memberAccessOperation postfixUnaryExpression // TODO: Review
412         *   ;
413         */
414        private void parsePostfixExpression() {
415            PsiBuilder.Marker expression = mark();
416    
417            boolean callableReference = parseCallableReferenceExpression();
418            if (!callableReference) {
419                parseAtomicExpression();
420            }
421    
422            while (true) {
423                if (interruptedWithNewLine()) {
424                    break;
425                }
426                else if (at(LBRACKET)) {
427                    parseArrayAccess();
428                    expression.done(ARRAY_ACCESS_EXPRESSION);
429                }
430                else if (!callableReference && parseCallSuffix()) {
431                    expression.done(CALL_EXPRESSION);
432                }
433                else if (at(DOT)) {
434                    advance(); // DOT
435    
436                    parseCallExpression();
437    
438                    expression.done(DOT_QUALIFIED_EXPRESSION);
439                }
440                else if (at(SAFE_ACCESS)) {
441                    advance(); // SAFE_ACCESS
442    
443                    parseCallExpression();
444    
445                    expression.done(SAFE_ACCESS_EXPRESSION);
446                }
447                else if (atSet(Precedence.POSTFIX.getOperations())) {
448                    parseOperationReference();
449                    expression.done(POSTFIX_EXPRESSION);
450                }
451                else {
452                    break;
453                }
454                expression = expression.precede();
455            }
456            expression.drop();
457        }
458    
459        /*
460         * callSuffix
461         *   : typeArguments? valueArguments (getEntryPoint? functionLiteral*)
462         *   : typeArguments (getEntryPoint? functionLiteral*)
463         *   ;
464         */
465        private boolean parseCallSuffix() {
466            if (parseCallWithClosure()) {
467                parseCallWithClosure();
468            }
469            else if (at(LPAR)) {
470                parseValueArgumentList();
471                parseCallWithClosure();
472            }
473            else if (at(LT)) {
474                PsiBuilder.Marker typeArgumentList = mark();
475                if (myJetParsing.tryParseTypeArgumentList(TYPE_ARGUMENT_LIST_STOPPERS)) {
476                    typeArgumentList.done(TYPE_ARGUMENT_LIST);
477                    if (!myBuilder.newlineBeforeCurrentToken() && at(LPAR)) parseValueArgumentList();
478                    parseCallWithClosure();
479                }
480                else {
481                    typeArgumentList.rollbackTo();
482                    return false;
483                }
484            }
485            else {
486                return false;
487            }
488    
489            return true;
490        }
491    
492        /*
493         * atomicExpression typeParameters? valueParameters? functionLiteral*
494         */
495        private void parseCallExpression() {
496            PsiBuilder.Marker mark = mark();
497            parseAtomicExpression();
498            if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) {
499                mark.done(CALL_EXPRESSION);
500            }
501            else {
502                mark.drop();
503            }
504        }
505    
506        private void parseOperationReference() {
507            PsiBuilder.Marker operationReference = mark();
508            advance(); // operation
509            operationReference.done(OPERATION_REFERENCE);
510        }
511    
512        /*
513         * element (getEntryPoint? functionLiteral)?
514         */
515        protected boolean parseCallWithClosure() {
516            boolean success = false;
517            while ((at(LBRACE) || at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE)) {
518                PsiBuilder.Marker argument = mark();
519                if (!at(LBRACE)) {
520                    assert _at(LABEL_IDENTIFIER);
521                    parseLabeledExpression();
522                }
523                else {
524                    parseFunctionLiteral();
525                }
526                argument.done(FUNCTION_LITERAL_ARGUMENT);
527                success = true;
528            }
529    
530            return success;
531        }
532    
533        /*
534         * atomicExpression
535         *   : tupleLiteral // or parenthesized element
536         *   : "this" label?
537         *   : "super" ("<" type ">")? label?
538         *   : objectLiteral
539         *   : jump
540         *   : if
541         *   : when
542         *   : try
543         *   : loop
544         *   : literalConstant
545         *   : functionLiteral
546         *   : declaration
547         *   : SimpleName
548         *   : "package" // for the root package
549         *   ;
550         */
551        private void parseAtomicExpression() {
552            //        System.out.println("atom at "  + myBuilder.getTokenText());
553    
554            if (at(LPAR)) {
555                parseParenthesizedExpression();
556            }
557            else if (at(HASH)) {
558                parseTupleExpression();
559            }
560            else if (at(PACKAGE_KEYWORD)) {
561                parseOneTokenExpression(ROOT_PACKAGE);
562            }
563            else if (at(THIS_KEYWORD)) {
564                parseThisExpression();
565            }
566            else if (at(SUPER_KEYWORD)) {
567                parseSuperExpression();
568            }
569            else if (at(OBJECT_KEYWORD)) {
570                parseObjectLiteral();
571            }
572            else if (at(THROW_KEYWORD)) {
573                parseThrow();
574            }
575            else if (at(RETURN_KEYWORD)) {
576                parseReturn();
577            }
578            else if (at(CONTINUE_KEYWORD)) {
579                parseJump(CONTINUE);
580            }
581            else if (at(BREAK_KEYWORD)) {
582                parseJump(BREAK);
583            }
584            else if (at(IF_KEYWORD)) {
585                parseIf();
586            }
587            else if (at(WHEN_KEYWORD)) {
588                parseWhen();
589            }
590            else if (at(TRY_KEYWORD)) {
591                parseTry();
592            }
593            else if (at(FOR_KEYWORD)) {
594                parseFor();
595            }
596            else if (at(WHILE_KEYWORD)) {
597                parseWhile();
598            }
599            else if (at(DO_KEYWORD)) {
600                parseDoWhile();
601            }
602            else if (atSet(CLASS_KEYWORD, FUN_KEYWORD, VAL_KEYWORD,
603                           VAR_KEYWORD, TYPE_ALIAS_KEYWORD)) {
604                parseLocalDeclaration();
605            }
606            else if (at(FIELD_IDENTIFIER)) {
607                parseSimpleNameExpression();
608            }
609            else if (at(IDENTIFIER)) {
610                parseSimpleNameExpression();
611            }
612            else if (at(LBRACE)) {
613                parseFunctionLiteral();
614            }
615            else if (at(OPEN_QUOTE)) {
616                parseStringTemplate();
617            }
618            else if (!parseLiteralConstant()) {
619                // TODO: better recovery if FIRST(element) did not match
620                errorWithRecovery("Expecting an element", EXPRESSION_FOLLOW);
621            }
622        }
623    
624        /*
625         * stringTemplate
626         *   : OPEN_QUOTE stringTemplateElement* CLOSING_QUOTE
627         *   ;
628         */
629        private void parseStringTemplate() {
630            assert _at(OPEN_QUOTE);
631    
632            PsiBuilder.Marker template = mark();
633    
634            advance(); // OPEN_QUOTE
635    
636            while (!eof()) {
637                if (at(CLOSING_QUOTE) || at(DANGLING_NEWLINE)) {
638                    break;
639                }
640                parseStringTemplateElement();
641            }
642    
643            if (at(DANGLING_NEWLINE)) {
644                errorAndAdvance("Expecting '\"'");
645            }
646            else {
647                expect(CLOSING_QUOTE, "Expecting '\"'");
648            }
649            template.done(STRING_TEMPLATE);
650        }
651    
652        /*
653         * stringTemplateElement
654         *   : RegularStringPart
655         *   : ShortTemplateEntrySTART (SimpleName | "this")
656         *   : EscapeSequence
657         *   : longTemplate
658         *   ;
659         *
660         * longTemplate
661         *   : "${" expression "}"
662         *   ;
663         */
664        private void parseStringTemplateElement() {
665            if (at(REGULAR_STRING_PART)) {
666                PsiBuilder.Marker mark = mark();
667                advance(); // REGULAR_STRING_PART
668                mark.done(LITERAL_STRING_TEMPLATE_ENTRY);
669            }
670            else if (at(ESCAPE_SEQUENCE)) {
671                PsiBuilder.Marker mark = mark();
672                advance(); // ESCAPE_SEQUENCE
673                mark.done(ESCAPE_STRING_TEMPLATE_ENTRY);
674            }
675            else if (at(SHORT_TEMPLATE_ENTRY_START)) {
676                PsiBuilder.Marker entry = mark();
677                advance(); // SHORT_TEMPLATE_ENTRY_START
678    
679                if (at(THIS_KEYWORD)) {
680                    PsiBuilder.Marker thisExpression = mark();
681                    PsiBuilder.Marker reference = mark();
682                    advance(); // THIS_KEYWORD
683                    reference.done(REFERENCE_EXPRESSION);
684                    thisExpression.done(THIS_EXPRESSION);
685                }
686                else {
687                    JetToken keyword = KEYWORD_TEXTS.get(myBuilder.getTokenText());
688                    if (keyword != null) {
689                        myBuilder.remapCurrentToken(keyword);
690                        errorAndAdvance("Keyword cannot be used as a reference");
691                    }
692                    else {
693                        PsiBuilder.Marker reference = mark();
694                        expect(IDENTIFIER, "Expecting a name");
695                        reference.done(REFERENCE_EXPRESSION);
696                    }
697                }
698    
699                entry.done(SHORT_STRING_TEMPLATE_ENTRY);
700            }
701            else if (at(LONG_TEMPLATE_ENTRY_START)) {
702                PsiBuilder.Marker longTemplateEntry = mark();
703    
704                advance(); // LONG_TEMPLATE_ENTRY_START
705    
706                parseExpression();
707    
708                expect(LONG_TEMPLATE_ENTRY_END, "Expecting '}'", TokenSet.create(CLOSING_QUOTE, DANGLING_NEWLINE, REGULAR_STRING_PART, ESCAPE_SEQUENCE, SHORT_TEMPLATE_ENTRY_START));
709                longTemplateEntry.done(LONG_STRING_TEMPLATE_ENTRY);
710            }
711            else {
712                errorAndAdvance("Unexpected token in a string template");
713            }
714        }
715    
716        /*
717         * literalConstant
718         *   : "true" | "false"
719         *   : StringWithTemplates
720         *   : NoEscapeString
721         *   : IntegerLiteral
722         *   : LongLiteral
723         *   : CharacterLiteral
724         *   : FloatLiteral
725         *   : "null"
726         *   ;
727         */
728        private boolean parseLiteralConstant() {
729            if (at(TRUE_KEYWORD) || at(FALSE_KEYWORD)) {
730                parseOneTokenExpression(BOOLEAN_CONSTANT);
731            }
732            else if (at(INTEGER_LITERAL)) {
733                parseOneTokenExpression(INTEGER_CONSTANT);
734            }
735            else if (at(CHARACTER_LITERAL)) {
736                parseOneTokenExpression(CHARACTER_CONSTANT);
737            }
738            else if (at(FLOAT_LITERAL)) {
739                parseOneTokenExpression(FLOAT_CONSTANT);
740            }
741            else if (at(NULL_KEYWORD)) {
742                parseOneTokenExpression(NULL);
743            }
744            else {
745                return false;
746            }
747            return true;
748        }
749    
750        /*
751         * when
752         *   : "when" ("(" (modifiers "val" SimpleName "=")? element ")")? "{"
753         *         whenEntry*
754         *     "}"
755         *   ;
756         */
757        private void parseWhen() {
758            assert _at(WHEN_KEYWORD);
759    
760            PsiBuilder.Marker when = mark();
761    
762            advance(); // WHEN_KEYWORD
763    
764            // Parse condition
765            myBuilder.disableNewlines();
766            if (at(LPAR)) {
767                advanceAt(LPAR);
768    
769                int valPos = matchTokenStreamPredicate(new FirstBefore(new At(VAL_KEYWORD), new AtSet(RPAR, LBRACE, RBRACE, SEMICOLON, EQ)));
770                if (valPos >= 0) {
771                    PsiBuilder.Marker property = mark();
772                    myJetParsing.parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
773                    myJetParsing.parseProperty(true);
774                    property.done(PROPERTY);
775                }
776                else {
777                    parseExpression();
778                }
779    
780                expect(RPAR, "Expecting ')'");
781            }
782            myBuilder.restoreNewlinesState();
783    
784            // Parse when block
785            myBuilder.enableNewlines();
786            if (expect(LBRACE, "Expecting '{'")) {
787                while (!eof() && !at(RBRACE)) {
788                    parseWhenEntry();
789                }
790    
791                expect(RBRACE, "Expecting '}'");
792            }
793            myBuilder.restoreNewlinesState();
794    
795            when.done(WHEN);
796        }
797    
798        /*
799         * whenEntry
800         *   // TODO : consider empty after ->
801         *   : whenCondition{","} "->" element SEMI
802         *   : "else" "->" element SEMI
803         *   ;
804         */
805        private void parseWhenEntry() {
806            PsiBuilder.Marker entry = mark();
807    
808            if (at(ELSE_KEYWORD)) {
809                advance(); // ELSE_KEYWORD
810    
811                if (!at(ARROW)) {
812                    errorUntil("Expecting '->'", TokenSet.create(ARROW,
813                                                                 RBRACE, EOL_OR_SEMICOLON));
814                }
815    
816                if (at(ARROW)) {
817                    advance(); // ARROW
818    
819                    if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
820                        error("Expecting an element");
821                    }
822                    else {
823                        parseExpressionPreferringBlocks();
824                    }
825                }
826                else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
827                    errorAndAdvance("Expecting '->'");
828                }
829            }
830            else {
831                parseWhenEntryNotElse();
832            }
833    
834            entry.done(WHEN_ENTRY);
835            consumeIf(SEMICOLON);
836        }
837    
838        /*
839         * : whenCondition{","} "->" element SEMI
840         */
841        private void parseWhenEntryNotElse() {
842            while (true) {
843                while (at(COMMA)) errorAndAdvance("Expecting a when-condition");
844                parseWhenCondition();
845                if (!at(COMMA)) break;
846                advance(); // COMMA
847            }
848    
849            expect(ARROW, "Expecting '->' or 'when'", WHEN_CONDITION_RECOVERY_SET);
850            if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
851                error("Expecting an element");
852            }
853            else {
854                parseExpressionPreferringBlocks();
855            }
856            // SEMI is consumed in parseWhenEntry
857        }
858    
859        /*
860         * whenCondition
861         *   : expression
862         *   : ("in" | "!in") expression
863         *   : ("is" | "!is") isRHS
864         *   ;
865         */
866        private void parseWhenCondition() {
867            PsiBuilder.Marker condition = mark();
868            myBuilder.disableNewlines();
869            if (at(IN_KEYWORD) || at(NOT_IN)) {
870                PsiBuilder.Marker mark = mark();
871                advance(); // IN_KEYWORD or NOT_IN
872                mark.done(OPERATION_REFERENCE);
873    
874    
875                if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
876                    error("Expecting an element");
877                }
878                else {
879                    parseExpression();
880                }
881                condition.done(WHEN_CONDITION_IN_RANGE);
882            }
883            else if (at(IS_KEYWORD) || at(NOT_IS)) {
884                advance(); // IS_KEYWORD or NOT_IS
885    
886                if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
887                    error("Expecting a type");
888                }
889                else {
890                    myJetParsing.parseTypeRef();
891                }
892                condition.done(WHEN_CONDITION_IS_PATTERN);
893            }
894            else {
895                if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
896                    error("Expecting an expression, is-condition or in-condition");
897                }
898                else {
899                    parseExpression();
900                }
901                condition.done(WHEN_CONDITION_EXPRESSION);
902            }
903            myBuilder.restoreNewlinesState();
904        }
905    
906        /*
907         * arrayAccess
908         *   : "[" element{","} "]"
909         *   ;
910         */
911        private void parseArrayAccess() {
912            assert _at(LBRACKET);
913    
914            PsiBuilder.Marker indices = mark();
915    
916            myBuilder.disableNewlines();
917            advance(); // LBRACKET
918    
919            while (true) {
920                if (at(COMMA)) errorAndAdvance("Expecting an index element");
921                if (at(RBRACKET)) {
922                    error("Expecting an index element");
923                    break;
924                }
925                parseExpression();
926                if (!at(COMMA)) break;
927                advance(); // COMMA
928            }
929    
930            expect(RBRACKET, "Expecting ']'");
931            myBuilder.restoreNewlinesState();
932    
933            indices.done(INDICES);
934        }
935    
936        /*
937         * SimpleName
938         */
939        public void parseSimpleNameExpression() {
940            PsiBuilder.Marker simpleName = mark();
941            if (at(FIELD_IDENTIFIER)) {
942                advance(); //
943            }
944            else {
945                expect(IDENTIFIER, "Expecting an identifier");
946            }
947            simpleName.done(REFERENCE_EXPRESSION);
948        }
949    
950        /*
951         * modifiers declarationRest
952         */
953        private boolean parseLocalDeclaration() {
954            PsiBuilder.Marker decl = mark();
955            JetParsing.TokenDetector enumDetector = new JetParsing.TokenDetector(ENUM_KEYWORD);
956            myJetParsing.parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
957    
958            IElementType declType = parseLocalDeclarationRest(enumDetector.isDetected());
959    
960            if (declType != null) {
961                decl.done(declType);
962                return true;
963            }
964            else {
965                decl.rollbackTo();
966                return false;
967            }
968        }
969    
970        /*
971         * functionLiteral  // one can use "it" as a parameter name
972         *   : "{" expressions "}"
973         *   : "{" (modifiers SimpleName){","} "->" statements "}"
974         *   : "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "->" expressions "}"
975         *   ;
976         */
977        private void parseFunctionLiteral() {
978            parseFunctionLiteral(false);
979        }
980    
981        private void parseFunctionLiteral(boolean preferBlock) {
982            assert _at(LBRACE);
983    
984            PsiBuilder.Marker literalExpression = mark();
985    
986            PsiBuilder.Marker literal = mark();
987    
988            myBuilder.enableNewlines();
989            advance(); // LBRACE
990    
991            boolean paramsFound = false;
992    
993            if (at(ARROW)) {
994                //   { -> ...}
995                mark().done(VALUE_PARAMETER_LIST);
996                advance(); // ARROW
997                paramsFound = true;
998            }
999            else if (at(LPAR)) {
1000                // Look for ARROW after matching RPAR
1001                //   {(a, b) -> ...}
1002    
1003                {
1004                    boolean preferParamsToExpressions = isConfirmedParametersByComma();
1005    
1006                    PsiBuilder.Marker rollbackMarker = mark();
1007                    parseFunctionLiteralParametersAndType();
1008    
1009                    paramsFound = preferParamsToExpressions ?
1010                                  rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
1011                                  rollbackOrDropAt(rollbackMarker, ARROW);
1012                }
1013    
1014                if (!paramsFound) {
1015                    // If not found, try a typeRef DOT and then LPAR .. RPAR ARROW
1016                    //   {((A) -> B).(x) -> ... }
1017                    paramsFound = parseFunctionTypeDotParametersAndType();
1018                }
1019            }
1020            else {
1021                if (at(IDENTIFIER)) {
1022                    // Try to parse a simple name list followed by an ARROW
1023                    //   {a -> ...}
1024                    //   {a, b -> ...}
1025                    PsiBuilder.Marker rollbackMarker = mark();
1026                    boolean preferParamsToExpressions = (lookahead(1) == COMMA);
1027                    parseFunctionLiteralShorthandParameterList();
1028                    parseOptionalFunctionLiteralType();
1029    
1030                    paramsFound = preferParamsToExpressions ?
1031                                  rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
1032                                  rollbackOrDropAt(rollbackMarker, ARROW);
1033                }
1034                if (!paramsFound && atSet(JetParsing.TYPE_REF_FIRST)) {
1035                    // Try to parse a type DOT valueParameterList ARROW
1036                    //   {A.(b) -> ...}
1037                    paramsFound = parseFunctionTypeDotParametersAndType();
1038                }
1039            }
1040    
1041            if (!paramsFound) {
1042                if (preferBlock) {
1043                    literal.drop();
1044                    parseStatements();
1045                    expect(RBRACE, "Expecting '}'");
1046                    literalExpression.done(BLOCK);
1047                    myBuilder.restoreNewlinesState();
1048    
1049                    return;
1050                }
1051            }
1052    
1053            PsiBuilder.Marker body = mark();
1054            parseStatements();
1055            body.done(BLOCK);
1056    
1057            expect(RBRACE, "Expecting '}'");
1058            myBuilder.restoreNewlinesState();
1059    
1060            literal.done(FUNCTION_LITERAL);
1061            literalExpression.done(FUNCTION_LITERAL_EXPRESSION);
1062        }
1063    
1064        private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) {
1065            if (at(dropAt)) {
1066                advance(); // dropAt
1067                rollbackMarker.drop();
1068                return true;
1069            }
1070            rollbackMarker.rollbackTo();
1071            return false;
1072        }
1073    
1074        private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker,
1075                JetToken expected, String expectMessage,
1076                IElementType validForDrop) {
1077            if (at(expected)) {
1078                advance(); // dropAt
1079                rollbackMarker.drop();
1080                return true;
1081            }
1082            else if (at(validForDrop)) {
1083                rollbackMarker.drop();
1084                expect(expected, expectMessage);
1085                return true;
1086            }
1087    
1088            rollbackMarker.rollbackTo();
1089            return false;
1090        }
1091    
1092    
1093        /*
1094         * SimpleName{,}
1095         */
1096        private void parseFunctionLiteralShorthandParameterList() {
1097            PsiBuilder.Marker parameterList = mark();
1098    
1099            while (!eof()) {
1100                PsiBuilder.Marker parameter = mark();
1101    
1102                //            int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
1103                //            createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
1104    
1105                expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
1106    
1107                parameter.done(VALUE_PARAMETER);
1108    
1109                if (at(COLON)) {
1110                    PsiBuilder.Marker errorMarker = mark();
1111                    advance(); // COLON
1112                    myJetParsing.parseTypeRef();
1113                    errorMarker.error("To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType -> ...}");
1114                }
1115                else if (at(ARROW)) {
1116                    break;
1117                }
1118                else if (at(COMMA)) {
1119                    advance(); // COMMA
1120                }
1121                else {
1122                    error("Expecting '->' or ','");
1123                    break;
1124                }
1125            }
1126    
1127            parameterList.done(VALUE_PARAMETER_LIST);
1128        }
1129    
1130        // Check that position is followed by top level comma. It can't be expression and we want it be
1131        // parsed as parameters in function literal
1132        private boolean isConfirmedParametersByComma() {
1133            assert _at(LPAR);
1134            PsiBuilder.Marker lparMarker = mark();
1135            advance(); // LPAR
1136            int comma = matchTokenStreamPredicate(new FirstBefore(new At(COMMA), new AtSet(ARROW, RPAR)));
1137            lparMarker.rollbackTo();
1138            return comma > 0;
1139        }
1140    
1141        private boolean parseFunctionTypeDotParametersAndType() {
1142            PsiBuilder.Marker rollbackMarker = mark();
1143    
1144            // True when it's confirmed that body of literal can't be simple expressions and we prefer to parse
1145            // it to function params if possible.
1146            boolean preferParamsToExpressions = false;
1147    
1148            int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR)));
1149            if (lastDot >= 0) {
1150                createTruncatedBuilder(lastDot).parseTypeRef();
1151                if (at(DOT)) {
1152                    advance(); // DOT
1153    
1154                    if (at(LPAR)) {
1155                        preferParamsToExpressions = isConfirmedParametersByComma();
1156                    }
1157    
1158                    parseFunctionLiteralParametersAndType();
1159                }
1160            }
1161    
1162            return preferParamsToExpressions ?
1163                   rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
1164                   rollbackOrDropAt(rollbackMarker, ARROW);
1165        }
1166    
1167        private void parseFunctionLiteralParametersAndType() {
1168            parseFunctionLiteralParameterList();
1169            parseOptionalFunctionLiteralType();
1170        }
1171    
1172        /*
1173         * (":" type)?
1174         */
1175        private void parseOptionalFunctionLiteralType() {
1176            if (at(COLON)) {
1177                advance(); // COLON
1178                if (at(ARROW)) {
1179                    error("Expecting a type");
1180                }
1181                else {
1182                    myJetParsing.parseTypeRef();
1183                }
1184            }
1185        }
1186    
1187        /*
1188         * "(" (modifiers SimpleName (":" type)?){","} ")"
1189         */
1190        private void parseFunctionLiteralParameterList() {
1191            PsiBuilder.Marker list = mark();
1192            expect(LPAR, "Expecting a parameter list in parentheses (...)", TokenSet.create(ARROW, COLON));
1193    
1194            myBuilder.disableNewlines();
1195    
1196            if (!at(RPAR)) {
1197                while (true) {
1198                    if (at(COMMA)) errorAndAdvance("Expecting a parameter declaration");
1199    
1200                    PsiBuilder.Marker parameter = mark();
1201                    int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, ARROW)));
1202                    createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1203    
1204                    expect(IDENTIFIER, "Expecting parameter declaration");
1205    
1206                    if (at(COLON)) {
1207                        advance(); // COLON
1208                        myJetParsing.parseTypeRef();
1209                    }
1210                    parameter.done(VALUE_PARAMETER);
1211                    if (!at(COMMA)) break;
1212                    advance(); // COMMA
1213    
1214                    if (at(RPAR)) {
1215                        error("Expecting a parameter declaration");
1216                        break;
1217                    }
1218                }
1219            }
1220    
1221            myBuilder.restoreNewlinesState();
1222    
1223            expect(RPAR, "Expecting ')", TokenSet.create(ARROW, COLON));
1224            list.done(VALUE_PARAMETER_LIST);
1225        }
1226    
1227        /*
1228         * expressions
1229         *   : SEMI* statement{SEMI+} SEMI*
1230         */
1231        public void parseStatements() {
1232            while (at(SEMICOLON)) advance(); // SEMICOLON
1233            while (!eof() && !at(RBRACE)) {
1234                if (!atSet(STATEMENT_FIRST)) {
1235                    errorAndAdvance("Expecting an element");
1236                }
1237                if (atSet(STATEMENT_FIRST)) {
1238                    parseStatement();
1239                }
1240                if (at(SEMICOLON)) {
1241                    while (at(SEMICOLON)) advance(); // SEMICOLON
1242                }
1243                else if (at(RBRACE)) {
1244                    break;
1245                }
1246                else if (!myBuilder.newlineBeforeCurrentToken()) {
1247                    String severalStatementsError = "Unexpected tokens (use ';' to separate expressions on the same line)";
1248    
1249                    if (atSet(STATEMENT_NEW_LINE_QUICK_RECOVERY_SET)) {
1250                        error(severalStatementsError);
1251                    }
1252                    else {
1253                        errorUntil(severalStatementsError, TokenSet.create(EOL_OR_SEMICOLON));
1254                    }
1255                }
1256            }
1257        }
1258    
1259        /*
1260         * statement
1261         *  : expression
1262         *  : declaration
1263         *  ;
1264         */
1265        private void parseStatement() {
1266            if (!parseLocalDeclaration()) {
1267                if (!atSet(EXPRESSION_FIRST)) {
1268                    errorAndAdvance("Expecting a statement");
1269                }
1270                else {
1271                    parseExpression();
1272                }
1273            }
1274        }
1275    
1276        /*
1277         * declaration
1278         *   : function
1279         *   : property
1280         *   : extension
1281         *   : class
1282         *   : typeAlias
1283         *   : object
1284         *   ;
1285         */
1286        private IElementType parseLocalDeclarationRest(boolean isEnum) {
1287            IElementType keywordToken = tt();
1288            IElementType declType = null;
1289            if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD) {
1290                declType = myJetParsing.parseClass(isEnum);
1291            }
1292            else if (keywordToken == FUN_KEYWORD) {
1293                declType = myJetParsing.parseFunction();
1294            }
1295            else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
1296                declType = myJetParsing.parseProperty(true);
1297            }
1298            else if (keywordToken == TYPE_ALIAS_KEYWORD) {
1299                declType = myJetParsing.parseTypeAlias();
1300            }
1301            else if (keywordToken == OBJECT_KEYWORD) {
1302                // Object expression may appear at the statement position: should parse it
1303                // as expression instead of object declaration
1304                // sample:
1305                // {
1306                //   object : Thread() {
1307                //   }
1308                // }
1309                IElementType lookahead = lookahead(1);
1310                if (lookahead == COLON || lookahead == LBRACE) {
1311                    return null;
1312                }
1313    
1314                myJetParsing.parseObject(true, true);
1315                declType = OBJECT_DECLARATION;
1316            }
1317            return declType;
1318        }
1319    
1320        /*
1321         * doWhile
1322         *   : "do" element "while" "(" element ")"
1323         *   ;
1324         */
1325        private void parseDoWhile() {
1326            assert _at(DO_KEYWORD);
1327    
1328            PsiBuilder.Marker loop = mark();
1329    
1330            advance(); // DO_KEYWORD
1331    
1332            if (!at(WHILE_KEYWORD)) {
1333                parseControlStructureBody();
1334            }
1335    
1336            if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) {
1337                parseCondition();
1338            }
1339    
1340            loop.done(DO_WHILE);
1341        }
1342    
1343        /*
1344         * while
1345         *   : "while" "(" element ")" element
1346         *   ;
1347         */
1348        private void parseWhile() {
1349            assert _at(WHILE_KEYWORD);
1350    
1351            PsiBuilder.Marker loop = mark();
1352    
1353            advance(); // WHILE_KEYWORD
1354    
1355            parseCondition();
1356    
1357            parseControlStructureBody();
1358    
1359            loop.done(WHILE);
1360        }
1361    
1362        /*
1363         * for
1364         *   : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
1365         *   ;
1366         *
1367         *   TODO: empty loop body (at the end of the block)?
1368         */
1369        private void parseFor() {
1370            assert _at(FOR_KEYWORD);
1371    
1372            PsiBuilder.Marker loop = mark();
1373    
1374            advance(); // FOR_KEYWORD
1375    
1376            if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) {
1377                myBuilder.disableNewlines();
1378    
1379                if (!at(RPAR)) {
1380                    PsiBuilder.Marker parameter = mark();
1381                    if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
1382                    if (at(LPAR)) {
1383                        myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
1384                        parameter.done(MULTI_VARIABLE_DECLARATION);
1385                    }
1386                    else {
1387                        expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
1388    
1389                        if (at(COLON)) {
1390                            advance(); // COLON
1391                            myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
1392                        }
1393                        parameter.done(VALUE_PARAMETER);
1394                    }
1395    
1396                    if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
1397                        PsiBuilder.Marker range = mark();
1398                        parseExpression();
1399                        range.done(LOOP_RANGE);
1400                    }
1401                }
1402                else {
1403                    error("Expecting a variable name");
1404                }
1405    
1406                expectNoAdvance(RPAR, "Expecting ')'");
1407                myBuilder.restoreNewlinesState();
1408            }
1409    
1410            parseControlStructureBody();
1411    
1412            loop.done(FOR);
1413        }
1414    
1415        /**
1416         * If it has no ->, it's a block, otherwise a function literal
1417         */
1418        private void parseExpressionPreferringBlocks() {
1419            if (at(LBRACE)) {
1420                parseFunctionLiteral(true);
1421            }
1422            else if (at(LABEL_IDENTIFIER) && lookahead(1) == LBRACE ) {
1423                PsiBuilder.Marker mark = mark();
1424    
1425                parseLabel();
1426    
1427                parseFunctionLiteral(true);
1428    
1429                mark.done(LABELED_EXPRESSION);
1430            }
1431            else {
1432                parseExpression();
1433            }
1434        }
1435    
1436        /*
1437         * element
1438         */
1439        private void parseControlStructureBody() {
1440            PsiBuilder.Marker body = mark();
1441            if (!at(SEMICOLON)) {
1442                parseExpressionPreferringBlocks();
1443            }
1444            body.done(BODY);
1445        }
1446    
1447        /*
1448         * try
1449         *   : "try" block catchBlock* finallyBlock?
1450         *   ;
1451         * catchBlock
1452         *   : "catch" "(" annotations SimpleName ":" userType ")" block
1453         *   ;
1454         *
1455         * finallyBlock
1456         *   : "finally" block
1457         *   ;
1458         */
1459        private void parseTry() {
1460            assert _at(TRY_KEYWORD);
1461    
1462            PsiBuilder.Marker tryExpression = mark();
1463    
1464            advance(); // TRY_KEYWORD
1465    
1466            myJetParsing.parseBlock();
1467    
1468            boolean catchOrFinally = false;
1469            while (at(CATCH_KEYWORD)) {
1470                catchOrFinally = true;
1471                PsiBuilder.Marker catchBlock = mark();
1472                advance(); // CATCH_KEYWORD
1473    
1474                TokenSet recoverySet = TokenSet.create(LBRACE, FINALLY_KEYWORD, CATCH_KEYWORD);
1475                if (atSet(recoverySet)) {
1476                    error("Expecting exception variable declaration");
1477                }
1478                else {
1479                    PsiBuilder.Marker parameters = mark();
1480                    expect(LPAR, "Expecting '('", recoverySet);
1481                    if (!atSet(recoverySet)) {
1482                        myJetParsing.parseValueParameter();
1483                        expect(RPAR, "Expecting ')'", recoverySet);
1484                    }
1485                    else {
1486                        error("Expecting exception variable declaration");
1487                    }
1488                    parameters.done(VALUE_PARAMETER_LIST);
1489                }
1490    
1491                if (at(LBRACE)) {
1492                    myJetParsing.parseBlock();
1493                }
1494                else {
1495                    error("Expecting a block: { ... }");
1496                }
1497                catchBlock.done(CATCH);
1498            }
1499    
1500            if (at(FINALLY_KEYWORD)) {
1501                catchOrFinally = true;
1502                PsiBuilder.Marker finallyBlock = mark();
1503    
1504                advance(); // FINALLY_KEYWORD
1505    
1506                myJetParsing.parseBlock();
1507    
1508                finallyBlock.done(FINALLY);
1509            }
1510    
1511            if (!catchOrFinally) {
1512                error("Expecting 'catch' or 'finally'");
1513            }
1514    
1515            tryExpression.done(TRY);
1516        }
1517    
1518        /*
1519         * if
1520         *   : "if" "(" element ")" element SEMI? ("else" element)?
1521         *   ;
1522         */
1523        private void parseIf() {
1524            assert _at(IF_KEYWORD);
1525    
1526            PsiBuilder.Marker marker = mark();
1527    
1528            advance(); //IF_KEYWORD
1529    
1530            parseCondition();
1531    
1532            PsiBuilder.Marker thenBranch = mark();
1533            if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) {
1534                parseExpressionPreferringBlocks();
1535            }
1536            if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) {
1537                advance(); // SEMICOLON
1538            }
1539            thenBranch.done(THEN);
1540    
1541            if (at(ELSE_KEYWORD)) {
1542                advance(); // ELSE_KEYWORD
1543    
1544                PsiBuilder.Marker elseBranch = mark();
1545                if (!at(SEMICOLON)) {
1546                    parseExpressionPreferringBlocks();
1547                }
1548                elseBranch.done(ELSE);
1549            }
1550    
1551            marker.done(IF);
1552        }
1553    
1554        /*
1555         * "(" element ")"
1556         */
1557        private void parseCondition() {
1558            myBuilder.disableNewlines();
1559    
1560            if (expect(LPAR, "Expecting a condition in parentheses '(...)'", EXPRESSION_FIRST)) {
1561                PsiBuilder.Marker condition = mark();
1562                parseExpression();
1563                condition.done(CONDITION);
1564                expect(RPAR, "Expecting ')");
1565            }
1566    
1567            myBuilder.restoreNewlinesState();
1568        }
1569    
1570        /*
1571         * : "continue" getEntryPoint?
1572         * : "break" getEntryPoint?
1573         */
1574        private void parseJump(JetNodeType type) {
1575            assert _at(BREAK_KEYWORD) || _at(CONTINUE_KEYWORD);
1576    
1577            PsiBuilder.Marker marker = mark();
1578    
1579            advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
1580    
1581            parseLabelOnTheSameLine();
1582    
1583            marker.done(type);
1584        }
1585    
1586        /*
1587         * "return" getEntryPoint? element?
1588         */
1589        private void parseReturn() {
1590            assert _at(RETURN_KEYWORD);
1591    
1592            PsiBuilder.Marker returnExpression = mark();
1593    
1594            advance(); // RETURN_KEYWORD
1595    
1596            parseLabelOnTheSameLine();
1597    
1598            if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
1599    
1600            returnExpression.done(RETURN);
1601        }
1602    
1603        /*
1604         * label?
1605         */
1606        private void parseLabelOnTheSameLine() {
1607            if (!eol() && at(LABEL_IDENTIFIER)) {
1608                parseLabel();
1609            }
1610        }
1611    
1612        /*
1613         * label
1614         */
1615        private void parseLabel() {
1616            assert _at(LABEL_IDENTIFIER);
1617    
1618            String labelText = myBuilder.getTokenText();
1619            if ("@".equals(labelText)) {
1620                errorAndAdvance("Label must be named");
1621                return;
1622            }
1623    
1624            PsiBuilder.Marker labelWrap = mark();
1625    
1626            PsiBuilder.Marker mark = mark();
1627            advance(); // LABEL_IDENTIFIER
1628            mark.done(LABEL);
1629    
1630            labelWrap.done(LABEL_QUALIFIER);
1631        }
1632    
1633        /*
1634         * : "throw" element
1635         */
1636        private void parseThrow() {
1637            assert _at(THROW_KEYWORD);
1638    
1639            PsiBuilder.Marker marker = mark();
1640    
1641            advance(); // THROW_KEYWORD
1642    
1643            parseExpression();
1644    
1645            marker.done(THROW);
1646        }
1647    
1648        /*
1649         * "(" expression ")"
1650         */
1651        private void parseParenthesizedExpression() {
1652            assert _at(LPAR);
1653    
1654            PsiBuilder.Marker mark = mark();
1655    
1656            myBuilder.disableNewlines();
1657            advance(); // LPAR
1658            if (at(RPAR)) {
1659                error("Expecting an expression");
1660            }
1661            else {
1662                parseExpression();
1663            }
1664    
1665            expect(RPAR, "Expecting ')'");
1666            myBuilder.restoreNewlinesState();
1667    
1668            mark.done(PARENTHESIZED);
1669        }
1670    
1671        /*
1672         * tupleLiteral
1673         *   : "#" "(" (((SimpleName "=")? expression){","})? ")"
1674         *   ;
1675         */
1676        @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1677        private void parseTupleExpression() {
1678            assert _at(HASH);
1679            PsiBuilder.Marker mark = mark();
1680    
1681            advance(); // HASH
1682            advance(); // LPAR
1683            myBuilder.disableNewlines();
1684            if (!at(RPAR)) {
1685                while (true) {
1686                    while (at(COMMA)) {
1687                        advance();
1688                    }
1689    
1690                    if (at(IDENTIFIER) && lookahead(1) == EQ) {
1691                        advance(); // IDENTIFIER
1692                        advance(); // EQ
1693                        parseExpression();
1694                    }
1695                    else {
1696                        parseExpression();
1697                    }
1698    
1699                    if (!at(COMMA)) break;
1700                    advance(); // COMMA
1701    
1702                    if (at(RPAR)) {
1703                        break;
1704                    }
1705                }
1706    
1707            }
1708            consumeIf(RPAR);
1709            myBuilder.restoreNewlinesState();
1710    
1711            mark.error("Tuples are not supported. Use data classes instead.");
1712        }
1713    
1714        /*
1715         * "this" label?
1716         */
1717        private void parseThisExpression() {
1718            assert _at(THIS_KEYWORD);
1719            PsiBuilder.Marker mark = mark();
1720    
1721            PsiBuilder.Marker thisReference = mark();
1722            advance(); // THIS_KEYWORD
1723            thisReference.done(REFERENCE_EXPRESSION);
1724    
1725            parseLabelOnTheSameLine();
1726    
1727            mark.done(THIS_EXPRESSION);
1728        }
1729    
1730        /*
1731         * "this" ("<" type ">")? label?
1732         */
1733        private void parseSuperExpression() {
1734            assert _at(SUPER_KEYWORD);
1735            PsiBuilder.Marker mark = mark();
1736    
1737            PsiBuilder.Marker superReference = mark();
1738            advance(); // SUPER_KEYWORD
1739            superReference.done(REFERENCE_EXPRESSION);
1740    
1741            if (at(LT)) {
1742                // This may be "super < foo" or "super<foo>", thus the backtracking
1743                PsiBuilder.Marker supertype = mark();
1744    
1745                myBuilder.disableNewlines();
1746                advance(); // LT
1747    
1748                myJetParsing.parseTypeRef();
1749    
1750                if (at(GT)) {
1751                    advance(); // GT
1752                    supertype.drop();
1753                }
1754                else {
1755                    supertype.rollbackTo();
1756                }
1757                myBuilder.restoreNewlinesState();
1758            }
1759            parseLabelOnTheSameLine();
1760    
1761            mark.done(SUPER_EXPRESSION);
1762        }
1763    
1764        /*
1765         * valueArguments
1766         *   : "(" (SimpleName "=")? "*"? element{","} ")"
1767         *   ;
1768         */
1769        public void parseValueArgumentList() {
1770            PsiBuilder.Marker list = mark();
1771    
1772            myBuilder.disableNewlines();
1773    
1774            if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) {
1775                if (!at(RPAR)) {
1776                    while (true) {
1777                        while (at(COMMA)) errorAndAdvance("Expecting an argument");
1778                        parseValueArgument();
1779                        if (!at(COMMA)) break;
1780                        advance(); // COMMA
1781                        if (at(RPAR)) {
1782                            error("Expecting an argument");
1783                            break;
1784                        }
1785                    }
1786                }
1787    
1788                expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW);
1789            }
1790    
1791            myBuilder.restoreNewlinesState();
1792    
1793            list.done(VALUE_ARGUMENT_LIST);
1794        }
1795    
1796        /*
1797         * (SimpleName "=")? "*"? element
1798         */
1799        private void parseValueArgument() {
1800            PsiBuilder.Marker argument = mark();
1801            if (at(IDENTIFIER) && lookahead(1) == EQ) {
1802                PsiBuilder.Marker argName = mark();
1803                PsiBuilder.Marker reference = mark();
1804                advance(); // IDENTIFIER
1805                reference.done(REFERENCE_EXPRESSION);
1806                argName.done(VALUE_ARGUMENT_NAME);
1807                advance(); // EQ
1808            }
1809            if (at(MUL)) {
1810                advance(); // MUL
1811            }
1812            parseExpression();
1813            argument.done(VALUE_ARGUMENT);
1814        }
1815    
1816        /*
1817         * "object" (":" delegationSpecifier{","})? classBody // Cannot make class body optional: foo(object : F, A)
1818         */
1819        public void parseObjectLiteral() {
1820            PsiBuilder.Marker literal = mark();
1821            PsiBuilder.Marker declaration = mark();
1822            myJetParsing.parseObject(false, false); // Body is not optional because of foo(object : A, B)
1823            declaration.done(OBJECT_DECLARATION);
1824            literal.done(OBJECT_LITERAL);
1825        }
1826    
1827        private void parseOneTokenExpression(JetNodeType type) {
1828            PsiBuilder.Marker mark = mark();
1829            advance();
1830            mark.done(type);
1831        }
1832    
1833        @Override
1834        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1835            return myJetParsing.create(builder);
1836        }
1837    
1838        private boolean interruptedWithNewLine() {
1839            return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
1840        }
1841    }