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