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