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