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.KtNodeType;
025    import org.jetbrains.kotlin.KtNodeTypes;
026    import org.jetbrains.kotlin.lexer.KtToken;
027    import org.jetbrains.kotlin.lexer.KtTokens;
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.KtNodeTypes.*;
035    import static org.jetbrains.kotlin.lexer.KtTokens.*;
036    import static org.jetbrains.kotlin.parsing.JetParsing.AnnotationParsingMode.DEFAULT;
037    import static org.jetbrains.kotlin.parsing.JetParsing.DeclarationParsingMode.LOCAL;
038    
039    public class JetExpressionParsing extends AbstractJetParsing {
040        private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD);
041        private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT);
042    
043    
044        private static final ImmutableMap<String, KtToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS);
045    
046        private static ImmutableMap<String, KtToken> tokenSetToMap(TokenSet tokens) {
047            ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder();
048            for (IElementType token : tokens.getTypes()) {
049                builder.put(token.toString(), (KtToken) token);
050            }
051            return builder.build();
052        }
053    
054        private static final TokenSet TYPE_ARGUMENT_LIST_STOPPERS = TokenSet.create(
055                INTEGER_LITERAL, FLOAT_LITERAL, CHARACTER_LITERAL, OPEN_QUOTE,
056                PACKAGE_KEYWORD, AS_KEYWORD, TYPE_ALIAS_KEYWORD, INTERFACE_KEYWORD, CLASS_KEYWORD, THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD,
057                FUN_KEYWORD, FOR_KEYWORD, NULL_KEYWORD,
058                TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD,
059                CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD,
060                WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL,
061                //            MUL,
062                PLUS, MINUS, EXCL, DIV, PERC, LTEQ,
063                // TODO GTEQ,   foo<bar, baz>=x
064                EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS,
065                SEMICOLON, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, NOT_IN, NOT_IS,
066                COLONCOLON,
067                COLON
068        );
069    
070        /*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.create(
071                // Prefix
072                MINUS, PLUS, MINUSMINUS, PLUSPLUS,
073                EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here
074                // Atomic
075    
076                COLONCOLON, // callable reference
077    
078                LPAR, // parenthesized
079    
080                // literal constant
081                TRUE_KEYWORD, FALSE_KEYWORD,
082                OPEN_QUOTE,
083                INTEGER_LITERAL, CHARACTER_LITERAL, FLOAT_LITERAL,
084                NULL_KEYWORD,
085    
086                LBRACE, // functionLiteral
087                FUN_KEYWORD, // expression function
088    
089                THIS_KEYWORD, // this
090                SUPER_KEYWORD, // super
091    
092                IF_KEYWORD, // if
093                WHEN_KEYWORD, // when
094                TRY_KEYWORD, // try
095                OBJECT_KEYWORD, // object
096    
097                // jump
098                THROW_KEYWORD,
099                RETURN_KEYWORD,
100                CONTINUE_KEYWORD,
101                BREAK_KEYWORD,
102    
103                // loop
104                FOR_KEYWORD,
105                WHILE_KEYWORD,
106                DO_KEYWORD,
107    
108                IDENTIFIER, // SimpleName
109                FIELD_IDENTIFIER, // Field reference
110    
111                PACKAGE_KEYWORD, // for absolute qualified names
112                AT // Just for better recovery and maybe for annotations
113        );
114    
115        private static final TokenSet STATEMENT_FIRST = TokenSet.orSet(
116                EXPRESSION_FIRST,
117                TokenSet.create(
118                        // declaration
119                        FUN_KEYWORD,
120                        VAL_KEYWORD, VAR_KEYWORD,
121                        INTERFACE_KEYWORD,
122                        CLASS_KEYWORD,
123                        TYPE_ALIAS_KEYWORD
124                ),
125                MODIFIER_KEYWORDS
126        );
127    
128        private static final TokenSet STATEMENT_NEW_LINE_QUICK_RECOVERY_SET =
129                TokenSet.orSet(
130                        TokenSet.andSet(STATEMENT_FIRST, TokenSet.andNot(KEYWORDS, TokenSet.create(IN_KEYWORD))),
131                        TokenSet.create(EOL_OR_SEMICOLON));
132    
133        /*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create(
134                SEMICOLON, ARROW, COMMA, RBRACE, RPAR, RBRACKET
135        );
136    
137        @SuppressWarnings({"UnusedDeclaration"})
138        public enum Precedence {
139            POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL,
140                    DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess
141    
142            PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // annotations
143    
144                @Override
145                public void parseHigherPrecedence(JetExpressionParsing parser) {
146                    throw new IllegalStateException("Don't call this method");
147                }
148            },
149    
150            AS(AS_KEYWORD, AS_SAFE) {
151                @Override
152                public KtNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
153                    parser.myJetParsing.parseTypeRef();
154                    return BINARY_WITH_TYPE;
155                }
156    
157                @Override
158                public void parseHigherPrecedence(JetExpressionParsing parser) {
159                    parser.parsePrefixExpression();
160                }
161            },
162    
163            MULTIPLICATIVE(MUL, DIV, PERC),
164            ADDITIVE(PLUS, MINUS),
165            RANGE(KtTokens.RANGE),
166            SIMPLE_NAME(IDENTIFIER),
167            ELVIS(KtTokens.ELVIS),
168            IN_OR_IS(IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS) {
169                @Override
170                public KtNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
171                    if (operation == IS_KEYWORD || operation == NOT_IS) {
172                        parser.myJetParsing.parseTypeRef();
173                        return IS_EXPRESSION;
174                    }
175    
176                    return super.parseRightHandSide(operation, parser);
177                }
178            },
179            COMPARISON(LT, GT, LTEQ, GTEQ),
180            EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ),
181            CONJUNCTION(ANDAND),
182            DISJUNCTION(OROR),
183            //        ARROW(KtTokens.ARROW),
184            ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
185            ;
186    
187            static {
188                Precedence[] values = Precedence.values();
189                for (Precedence precedence : values) {
190                    int ordinal = precedence.ordinal();
191                    precedence.higher = ordinal > 0 ? values[ordinal - 1] : null;
192                }
193            }
194    
195            private Precedence higher;
196            private final TokenSet operations;
197    
198            Precedence(IElementType... operations) {
199                this.operations = TokenSet.create(operations);
200            }
201    
202            public void parseHigherPrecedence(JetExpressionParsing parser) {
203                assert higher != null;
204                parser.parseBinaryExpression(higher);
205            }
206    
207            /**
208             *
209             * @param operation the operation sign (e.g. PLUS or IS)
210             * @param parser the parser object
211             * @return node type of the result
212             */
213            public KtNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
214                parseHigherPrecedence(parser);
215                return BINARY_EXPRESSION;
216            }
217    
218            @NotNull
219            public final TokenSet getOperations() {
220                return operations;
221            }
222        }
223    
224        public static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create(
225                DOT, SAFE_ACCESS,
226                COLON, AS_KEYWORD, AS_SAFE,
227                ELVIS,
228                // Can't allow `is` and `!is` because of when entry conditions: IS_KEYWORD, NOT_IS,
229                ANDAND,
230                OROR
231        );
232    
233        public static final TokenSet ALL_OPERATIONS;
234    
235        static {
236            Set<IElementType> operations = new HashSet<IElementType>();
237            Precedence[] values = Precedence.values();
238            for (Precedence precedence : values) {
239                operations.addAll(Arrays.asList(precedence.getOperations().getTypes()));
240            }
241            ALL_OPERATIONS = TokenSet.create(operations.toArray(new IElementType[operations.size()]));
242        }
243    
244        static {
245            IElementType[] operations = OPERATIONS.getTypes();
246            Set<IElementType> opSet = new HashSet<IElementType>(Arrays.asList(operations));
247            IElementType[] usedOperations = ALL_OPERATIONS.getTypes();
248            Set<IElementType> usedSet = new HashSet<IElementType>(Arrays.asList(usedOperations));
249    
250            if (opSet.size() > usedSet.size()) {
251                opSet.removeAll(usedSet);
252                assert false : opSet;
253            }
254            assert usedSet.size() == opSet.size() : "Either some ops are unused, or something a non-op is used";
255    
256            usedSet.removeAll(opSet);
257    
258            assert usedSet.isEmpty() : usedSet.toString();
259        }
260    
261    
262        private final JetParsing myJetParsing;
263    
264        public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
265            super(builder);
266            myJetParsing = jetParsing;
267        }
268    
269        /*
270         * element
271         *   : annotations element
272         *   : "(" element ")" // see tupleLiteral
273         *   : literalConstant
274         *   : functionLiteral
275         *   : tupleLiteral
276         *   : "null"
277         *   : "this" ("<" type ">")?
278         *   : expressionWithPrecedences
279         *   : if
280         *   : try
281         *   : "typeof" "(" element ")"
282         *   : "new" constructorInvocation
283         *   : objectLiteral
284         *   : declaration
285         *   : jump
286         *   : loop
287         *   // block is syntactically equivalent to a functionLiteral with no parameters
288         *   ;
289         */
290        public void parseExpression() {
291            if (!atSet(EXPRESSION_FIRST)) {
292                error("Expecting an expression");
293                return;
294            }
295            parseBinaryExpression(Precedence.ASSIGNMENT);
296        }
297    
298        /*
299         * element (operation element)*
300         *
301         * see the precedence table
302         */
303        private void parseBinaryExpression(Precedence precedence) {
304            //        System.out.println(precedence.name() + " at " + myBuilder.getTokenText());
305    
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            //        System.out.println("pre at "  + myBuilder.getTokenText());
338    
339            if (at(AT)) {
340                if (!parseLocalDeclaration()) {
341                    PsiBuilder.Marker expression = mark();
342                    myJetParsing.parseAnnotations(DEFAULT);
343                    parsePrefixExpression();
344                    expression.done(ANNOTATED_EXPRESSION);
345                }
346            }
347            else {
348                myBuilder.disableJoiningComplexTokens();
349                if (isAtLabelDefinitionOrMissingIdentifier()) {
350                    myBuilder.restoreJoiningComplexTokensState();
351                    parseLabeledExpression();
352                }
353                else if (atSet(Precedence.PREFIX.getOperations())) {
354                    PsiBuilder.Marker expression = mark();
355    
356                    parseOperationReference();
357    
358                    myBuilder.restoreJoiningComplexTokensState();
359    
360                    parsePrefixExpression();
361                    expression.done(PREFIX_EXPRESSION);
362                }
363                else {
364                    myBuilder.restoreJoiningComplexTokensState();
365                    parsePostfixExpression();
366                }
367            }
368        }
369    
370        /*
371         * callableReference
372         *   : (userType "?"*)? "::" SimpleName typeArguments?
373         *   ;
374         */
375        private boolean parseDoubleColonExpression() {
376            PsiBuilder.Marker expression = mark();
377    
378            if (!at(COLONCOLON)) {
379                PsiBuilder.Marker typeReference = mark();
380                myJetParsing.parseUserType();
381                typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
382                typeReference.done(TYPE_REFERENCE);
383    
384                if (!at(COLONCOLON)) {
385                    expression.rollbackTo();
386                    return false;
387                }
388            }
389    
390            advance(); // COLONCOLON
391    
392            if (at(CLASS_KEYWORD)) {
393                advance(); // CLASS_KEYWORD
394                expression.done(CLASS_LITERAL_EXPRESSION);
395            }
396            else {
397                parseSimpleNameExpression();
398    
399                if (at(LT)) {
400                    PsiBuilder.Marker typeArgumentList = mark();
401                    if (myJetParsing.tryParseTypeArgumentList(TYPE_ARGUMENT_LIST_STOPPERS)) {
402                        typeArgumentList.error("Type arguments are not allowed");
403                    }
404                    else {
405                        typeArgumentList.rollbackTo();
406                    }
407                }
408    
409                expression.done(CALLABLE_REFERENCE_EXPRESSION);
410            }
411    
412            return true;
413        }
414    
415        /*
416         * postfixUnaryExpression
417         *   : atomicExpression postfixUnaryOperation*
418         *   : callableReference postfixUnaryOperation*
419         *   ;
420         *
421         * postfixUnaryOperation
422         *   : "++" : "--" : "!!"
423         *   : typeArguments? valueArguments (getEntryPoint? functionLiteral)
424         *   : typeArguments (getEntryPoint? functionLiteral)
425         *   : arrayAccess
426         *   : memberAccessOperation postfixUnaryExpression // TODO: Review
427         *   ;
428         */
429        private void parsePostfixExpression() {
430            PsiBuilder.Marker expression = mark();
431    
432            boolean firstExpressionParsed;
433            boolean doubleColonExpression = parseDoubleColonExpression();
434            if (!doubleColonExpression) {
435                firstExpressionParsed = parseAtomicExpression();
436            }
437            else {
438                firstExpressionParsed = true;
439            }
440    
441            while (true) {
442                if (interruptedWithNewLine()) {
443                    break;
444                }
445                else if (at(LBRACKET)) {
446                    parseArrayAccess();
447                    expression.done(ARRAY_ACCESS_EXPRESSION);
448                }
449                else if (!doubleColonExpression && parseCallSuffix()) {
450                    expression.done(CALL_EXPRESSION);
451                }
452                else if (at(DOT) || at(SAFE_ACCESS)) {
453                    IElementType expressionType = at(DOT) ? DOT_QUALIFIED_EXPRESSION : SAFE_ACCESS_EXPRESSION;
454                    advance(); // DOT or SAFE_ACCESS
455    
456                    if (!firstExpressionParsed) {
457                        expression.drop();
458                        expression = mark();
459                    }
460    
461                    parseCallExpression();
462    
463                    if (firstExpressionParsed) {
464                        expression.done(expressionType);
465                    }
466                    else {
467                        firstExpressionParsed = true;
468                        continue;
469                    }
470                }
471                else if (atSet(Precedence.POSTFIX.getOperations())) {
472                    parseOperationReference();
473                    expression.done(POSTFIX_EXPRESSION);
474                }
475                else {
476                    break;
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 (myJetParsing.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 parseCallExpression() {
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(FUNCTION_LITERAL_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 = myJetParsing.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);
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 isAtLabelDefinitionBeforeLBrace() {
599            if (at(IDENTIFIER)) {
600                if (myBuilder.rawLookup(1) != AT) return false;
601                return lookahead(2) == LBRACE;
602            }
603    
604            return at(AT) && lookahead(1) == LBRACE;
605        }
606    
607        private boolean isAtLabelDefinitionOrMissingIdentifier() {
608            return (at(IDENTIFIER) && myBuilder.rawLookup(1) == AT) || at(AT);
609        }
610    
611        /*
612         * atomicExpression
613         *   : "this" label?
614         *   : "super" ("<" type ">")? label?
615         *   : objectLiteral
616         *   : jump
617         *   : if
618         *   : when
619         *   : try
620         *   : loop
621         *   : literalConstant
622         *   : functionLiteral
623         *   : declaration
624         *   : SimpleName
625         *   : "package" // for the root package
626         *   ;
627         */
628        private boolean parseAtomicExpression() {
629            //        System.out.println("atom at "  + myBuilder.getTokenText());
630    
631            boolean ok = true;
632    
633            if (at(LPAR)) {
634                parseParenthesizedExpression();
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                    KtToken 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                PsiBuilder.Marker property = mark();
849                myJetParsing.parseModifierList(DEFAULT, TokenSet.create(EQ, RPAR));
850                if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
851                    myJetParsing.parseProperty(true);
852                    property.done(PROPERTY);
853                }
854                else {
855                    property.rollbackTo();
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, DEFAULT, TokenSet.EMPTY);
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 != KtNodeTypes.PROPERTY && declType != KtNodeTypes.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         *   ;
1058         */
1059        private void parseFunctionLiteral() {
1060            parseFunctionLiteral(/* preferBlock = */false);
1061        }
1062    
1063        private void parseFunctionLiteral(boolean preferBlock) {
1064            assert _at(LBRACE);
1065    
1066            PsiBuilder.Marker literalExpression = mark();
1067    
1068            PsiBuilder.Marker literal = mark();
1069    
1070            myBuilder.enableNewlines();
1071            advance(); // LBRACE
1072    
1073            boolean paramsFound = false;
1074    
1075            if (at(ARROW)) {
1076                //   { -> ...}
1077                mark().done(VALUE_PARAMETER_LIST);
1078                advance(); // ARROW
1079                paramsFound = true;
1080            }
1081            else {
1082                if (at(IDENTIFIER) || at(COLON)) {
1083                    // Try to parse a simple name list followed by an ARROW
1084                    //   {a -> ...}
1085                    //   {a, b -> ...}
1086                    PsiBuilder.Marker rollbackMarker = mark();
1087                    IElementType nextToken = lookahead(1);
1088                    boolean preferParamsToExpressions = (nextToken == COMMA || nextToken == COLON);
1089                    parseFunctionLiteralShorthandParameterList();
1090    
1091                    paramsFound = preferParamsToExpressions ?
1092                                  rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
1093                                  rollbackOrDropAt(rollbackMarker, ARROW);
1094                }
1095            }
1096    
1097            if (!paramsFound) {
1098                if (preferBlock) {
1099                    literal.drop();
1100                    parseStatements();
1101                    expect(RBRACE, "Expecting '}'");
1102                    literalExpression.done(BLOCK);
1103                    myBuilder.restoreNewlinesState();
1104    
1105                    return;
1106                }
1107            }
1108    
1109            PsiBuilder.Marker body = mark();
1110            parseStatements();
1111            body.done(BLOCK);
1112    
1113            expect(RBRACE, "Expecting '}'");
1114            myBuilder.restoreNewlinesState();
1115    
1116            literal.done(FUNCTION_LITERAL);
1117            literalExpression.done(FUNCTION_LITERAL_EXPRESSION);
1118        }
1119    
1120        private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) {
1121            if (at(dropAt)) {
1122                advance(); // dropAt
1123                rollbackMarker.drop();
1124                return true;
1125            }
1126            rollbackMarker.rollbackTo();
1127            return false;
1128        }
1129    
1130        private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker,
1131                KtToken expected, String expectMessage,
1132                IElementType validForDrop) {
1133            if (at(expected)) {
1134                advance(); // dropAt
1135                rollbackMarker.drop();
1136                return true;
1137            }
1138            else if (at(validForDrop)) {
1139                rollbackMarker.drop();
1140                expect(expected, expectMessage);
1141                return true;
1142            }
1143    
1144            rollbackMarker.rollbackTo();
1145            return false;
1146        }
1147    
1148    
1149        /*
1150         * SimpleName{,}
1151         */
1152        private void parseFunctionLiteralShorthandParameterList() {
1153            PsiBuilder.Marker parameterList = mark();
1154    
1155            while (!eof()) {
1156                PsiBuilder.Marker parameter = mark();
1157    
1158                //            int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
1159                //            createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
1160    
1161                if (at(COLON)) {
1162                    error("Expecting parameter name");
1163                }
1164                else {
1165                    expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
1166                }
1167    
1168                if (at(COLON)) {
1169                    advance(); // COLON
1170                    myJetParsing.parseTypeRef(TokenSet.create(ARROW, COMMA));
1171                }
1172                parameter.done(VALUE_PARAMETER);
1173    
1174                if (at(ARROW)) {
1175                    break;
1176                }
1177                else if (at(COMMA)) {
1178                    advance(); // COMMA
1179                }
1180                else {
1181                    error("Expecting '->' or ','");
1182                    break;
1183                }
1184            }
1185    
1186            parameterList.done(VALUE_PARAMETER_LIST);
1187        }
1188    
1189        /*
1190         * expressions
1191         *   : SEMI* statement{SEMI+} SEMI*
1192         */
1193        public void parseStatements() {
1194            while (at(SEMICOLON)) advance(); // SEMICOLON
1195            while (!eof() && !at(RBRACE)) {
1196                if (!atSet(STATEMENT_FIRST)) {
1197                    errorAndAdvance("Expecting an element");
1198                }
1199                if (atSet(STATEMENT_FIRST)) {
1200                    parseStatement();
1201                }
1202                if (at(SEMICOLON)) {
1203                    while (at(SEMICOLON)) advance(); // SEMICOLON
1204                }
1205                else if (at(RBRACE)) {
1206                    break;
1207                }
1208                else if (!myBuilder.newlineBeforeCurrentToken()) {
1209                    String severalStatementsError = "Unexpected tokens (use ';' to separate expressions on the same line)";
1210    
1211                    if (atSet(STATEMENT_NEW_LINE_QUICK_RECOVERY_SET)) {
1212                        error(severalStatementsError);
1213                    }
1214                    else {
1215                        errorUntil(severalStatementsError, TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE));
1216                    }
1217                }
1218            }
1219        }
1220    
1221        /*
1222         * statement
1223         *  : expression
1224         *  : declaration
1225         *  ;
1226         */
1227        private void parseStatement() {
1228            if (!parseLocalDeclaration()) {
1229                if (!atSet(EXPRESSION_FIRST)) {
1230                    errorAndAdvance("Expecting a statement");
1231                }
1232                else {
1233                    parseExpression();
1234                }
1235            }
1236        }
1237    
1238        /*
1239         * declaration
1240         *   : function
1241         *   : property
1242         *   : extension
1243         *   : class
1244         *   : typeAlias
1245         *   : object
1246         *   ;
1247         */
1248        private IElementType parseLocalDeclarationRest(boolean isEnum) {
1249            IElementType keywordToken = tt();
1250            IElementType declType = null;
1251            if (keywordToken == CLASS_KEYWORD ||  keywordToken == INTERFACE_KEYWORD) {
1252                declType = myJetParsing.parseClass(isEnum, LOCAL);
1253            }
1254            else if (keywordToken == FUN_KEYWORD) {
1255                declType = myJetParsing.parseFunction();
1256            }
1257            else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
1258                declType = myJetParsing.parseProperty(true);
1259            }
1260            else if (keywordToken == TYPE_ALIAS_KEYWORD) {
1261                declType = myJetParsing.parseTypeAlias();
1262            }
1263            else if (keywordToken == OBJECT_KEYWORD) {
1264                // Object expression may appear at the statement position: should parse it
1265                // as expression instead of object declaration
1266                // sample:
1267                // {
1268                //   object : Thread() {
1269                //   }
1270                // }
1271                IElementType lookahead = lookahead(1);
1272                if (lookahead == COLON || lookahead == LBRACE) {
1273                    return null;
1274                }
1275    
1276                myJetParsing.parseObject(NameParsingMode.REQUIRED, true, LOCAL);
1277                declType = OBJECT_DECLARATION;
1278            }
1279            return declType;
1280        }
1281    
1282        /*
1283         * doWhile
1284         *   : "do" element "while" "(" element ")"
1285         *   ;
1286         */
1287        private void parseDoWhile() {
1288            assert _at(DO_KEYWORD);
1289    
1290            PsiBuilder.Marker loop = mark();
1291    
1292            advance(); // DO_KEYWORD
1293    
1294            if (!at(WHILE_KEYWORD)) {
1295                parseControlStructureBody();
1296            }
1297    
1298            if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) {
1299                parseCondition();
1300            }
1301    
1302            loop.done(DO_WHILE);
1303        }
1304    
1305        /*
1306         * while
1307         *   : "while" "(" element ")" element
1308         *   ;
1309         */
1310        private void parseWhile() {
1311            assert _at(WHILE_KEYWORD);
1312    
1313            PsiBuilder.Marker loop = mark();
1314    
1315            advance(); // WHILE_KEYWORD
1316    
1317            parseCondition();
1318    
1319            parseControlStructureBody();
1320    
1321            loop.done(WHILE);
1322        }
1323    
1324        /*
1325         * for
1326         *   : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
1327         *   ;
1328         *
1329         *   TODO: empty loop body (at the end of the block)?
1330         */
1331        private void parseFor() {
1332            assert _at(FOR_KEYWORD);
1333    
1334            PsiBuilder.Marker loop = mark();
1335    
1336            advance(); // FOR_KEYWORD
1337    
1338            if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) {
1339                myBuilder.disableNewlines();
1340    
1341                if (!at(RPAR)) {
1342                    PsiBuilder.Marker parameter = mark();
1343    
1344                    if (!at(IN_KEYWORD)) {
1345                        myJetParsing.parseModifierList(DEFAULT, TokenSet.create(IN_KEYWORD, RPAR, COLON));
1346                    }
1347    
1348                    if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
1349    
1350                    if (at(LPAR)) {
1351                        myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
1352                        parameter.done(MULTI_VARIABLE_DECLARATION);
1353                    }
1354                    else {
1355                        expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
1356    
1357                        if (at(COLON)) {
1358                            advance(); // COLON
1359                            myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
1360                        }
1361                        parameter.done(VALUE_PARAMETER);
1362                    }
1363    
1364                    if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
1365                        PsiBuilder.Marker range = mark();
1366                        parseExpression();
1367                        range.done(LOOP_RANGE);
1368                    }
1369                }
1370                else {
1371                    error("Expecting a variable name");
1372                }
1373    
1374                expectNoAdvance(RPAR, "Expecting ')'");
1375                myBuilder.restoreNewlinesState();
1376            }
1377    
1378            parseControlStructureBody();
1379    
1380            loop.done(FOR);
1381        }
1382    
1383        /**
1384         * If it has no ->, it's a block, otherwise a function literal
1385         */
1386        private void parseExpressionPreferringBlocks() {
1387            if (!parseAnnotatedLambda(/* preferBlock = */true)) {
1388                parseExpression();
1389            }
1390        }
1391    
1392        /*
1393         * element
1394         */
1395        private void parseControlStructureBody() {
1396            PsiBuilder.Marker body = mark();
1397            if (!at(SEMICOLON)) {
1398                parseExpressionPreferringBlocks();
1399            }
1400            body.done(BODY);
1401        }
1402    
1403        /*
1404         * try
1405         *   : "try" block catchBlock* finallyBlock?
1406         *   ;
1407         * catchBlock
1408         *   : "catch" "(" annotations SimpleName ":" userType ")" block
1409         *   ;
1410         *
1411         * finallyBlock
1412         *   : "finally" block
1413         *   ;
1414         */
1415        private void parseTry() {
1416            assert _at(TRY_KEYWORD);
1417    
1418            PsiBuilder.Marker tryExpression = mark();
1419    
1420            advance(); // TRY_KEYWORD
1421    
1422            myJetParsing.parseBlock();
1423    
1424            boolean catchOrFinally = false;
1425            while (at(CATCH_KEYWORD)) {
1426                catchOrFinally = true;
1427                PsiBuilder.Marker catchBlock = mark();
1428                advance(); // CATCH_KEYWORD
1429    
1430                TokenSet recoverySet = TokenSet.create(LBRACE, RBRACE, FINALLY_KEYWORD, CATCH_KEYWORD);
1431                if (atSet(recoverySet)) {
1432                    error("Expecting exception variable declaration");
1433                }
1434                else {
1435                    PsiBuilder.Marker parameters = mark();
1436                    expect(LPAR, "Expecting '('", recoverySet);
1437                    if (!atSet(recoverySet)) {
1438                        myJetParsing.parseValueParameter(/*typeRequired = */ true);
1439                        expect(RPAR, "Expecting ')'", recoverySet);
1440                    }
1441                    else {
1442                        error("Expecting exception variable declaration");
1443                    }
1444                    parameters.done(VALUE_PARAMETER_LIST);
1445                }
1446    
1447                if (at(LBRACE)) {
1448                    myJetParsing.parseBlock();
1449                }
1450                else {
1451                    error("Expecting a block: { ... }");
1452                }
1453                catchBlock.done(CATCH);
1454            }
1455    
1456            if (at(FINALLY_KEYWORD)) {
1457                catchOrFinally = true;
1458                PsiBuilder.Marker finallyBlock = mark();
1459    
1460                advance(); // FINALLY_KEYWORD
1461    
1462                myJetParsing.parseBlock();
1463    
1464                finallyBlock.done(FINALLY);
1465            }
1466    
1467            if (!catchOrFinally) {
1468                error("Expecting 'catch' or 'finally'");
1469            }
1470    
1471            tryExpression.done(TRY);
1472        }
1473    
1474        /*
1475         * if
1476         *   : "if" "(" element ")" element SEMI? ("else" element)?
1477         *   ;
1478         */
1479        private void parseIf() {
1480            assert _at(IF_KEYWORD);
1481    
1482            PsiBuilder.Marker marker = mark();
1483    
1484            advance(); //IF_KEYWORD
1485    
1486            parseCondition();
1487    
1488            PsiBuilder.Marker thenBranch = mark();
1489            if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) {
1490                parseExpressionPreferringBlocks();
1491            }
1492            if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) {
1493                advance(); // SEMICOLON
1494            }
1495            thenBranch.done(THEN);
1496    
1497            if (at(ELSE_KEYWORD)) {
1498                advance(); // ELSE_KEYWORD
1499    
1500                PsiBuilder.Marker elseBranch = mark();
1501                if (!at(SEMICOLON)) {
1502                    parseExpressionPreferringBlocks();
1503                }
1504                elseBranch.done(ELSE);
1505            }
1506    
1507            marker.done(IF);
1508        }
1509    
1510        /*
1511         * "(" element ")"
1512         */
1513        private void parseCondition() {
1514            myBuilder.disableNewlines();
1515    
1516            if (expect(LPAR, "Expecting a condition in parentheses '(...)'", EXPRESSION_FIRST)) {
1517                PsiBuilder.Marker condition = mark();
1518                parseExpression();
1519                condition.done(CONDITION);
1520                expect(RPAR, "Expecting ')");
1521            }
1522    
1523            myBuilder.restoreNewlinesState();
1524        }
1525    
1526        /*
1527         * : "continue" getEntryPoint?
1528         * : "break" getEntryPoint?
1529         */
1530        private void parseJump(KtNodeType type) {
1531            assert _at(BREAK_KEYWORD) || _at(CONTINUE_KEYWORD);
1532    
1533            PsiBuilder.Marker marker = mark();
1534    
1535            advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
1536    
1537            parseLabelReferenceWithNoWhitespace();
1538    
1539            marker.done(type);
1540        }
1541    
1542        /*
1543         * "return" getEntryPoint? element?
1544         */
1545        private void parseReturn() {
1546            assert _at(RETURN_KEYWORD);
1547    
1548            PsiBuilder.Marker returnExpression = mark();
1549    
1550            advance(); // RETURN_KEYWORD
1551    
1552            parseLabelReferenceWithNoWhitespace();
1553    
1554            if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
1555    
1556            returnExpression.done(RETURN);
1557        }
1558    
1559        /*
1560         * labelReference?
1561         */
1562        private void parseLabelReferenceWithNoWhitespace() {
1563            if (at(AT) && !myBuilder.newlineBeforeCurrentToken()) {
1564                if (WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) {
1565                    error("There should be no space or comments before '@' in label reference");
1566                }
1567                parseLabelReference();
1568            }
1569        }
1570    
1571        /*
1572         * IDENTIFIER "@"
1573         */
1574        private void parseLabelDefinition() {
1575            if (at(AT)) {
1576                // recovery for empty label identifier
1577                errorAndAdvance("Label must be named"); // AT
1578                return;
1579            }
1580    
1581            PsiBuilder.Marker labelWrap = mark();
1582            PsiBuilder.Marker mark = mark();
1583    
1584            assert _at(IDENTIFIER) && myBuilder.rawLookup(1) == AT : "Callers must check that current token is IDENTIFIER followed with '@'";
1585    
1586            advance(); // IDENTIFIER
1587            advance(); // AT
1588    
1589            mark.done(LABEL);
1590    
1591            labelWrap.done(LABEL_QUALIFIER);
1592        }
1593    
1594        /*
1595         * "@" IDENTIFIER
1596         */
1597        private void parseLabelReference() {
1598            assert _at(AT);
1599    
1600            PsiBuilder.Marker labelWrap = mark();
1601    
1602            PsiBuilder.Marker mark = mark();
1603    
1604            if (myBuilder.rawLookup(1) != IDENTIFIER) {
1605                errorAndAdvance("Label must be named"); // AT
1606                labelWrap.drop();
1607                mark.drop();
1608                return;
1609            }
1610    
1611            advance(); // AT
1612            advance(); // IDENTIFIER
1613    
1614            mark.done(LABEL);
1615    
1616            labelWrap.done(LABEL_QUALIFIER);
1617        }
1618    
1619        /*
1620         * : "throw" element
1621         */
1622        private void parseThrow() {
1623            assert _at(THROW_KEYWORD);
1624    
1625            PsiBuilder.Marker marker = mark();
1626    
1627            advance(); // THROW_KEYWORD
1628    
1629            parseExpression();
1630    
1631            marker.done(THROW);
1632        }
1633    
1634        /*
1635         * "(" expression ")"
1636         */
1637        private void parseParenthesizedExpression() {
1638            assert _at(LPAR);
1639    
1640            PsiBuilder.Marker mark = mark();
1641    
1642            myBuilder.disableNewlines();
1643            advance(); // LPAR
1644            if (at(RPAR)) {
1645                error("Expecting an expression");
1646            }
1647            else {
1648                parseExpression();
1649            }
1650    
1651            expect(RPAR, "Expecting ')'");
1652            myBuilder.restoreNewlinesState();
1653    
1654            mark.done(PARENTHESIZED);
1655        }
1656    
1657        /*
1658         * "this" label?
1659         */
1660        private void parseThisExpression() {
1661            assert _at(THIS_KEYWORD);
1662            PsiBuilder.Marker mark = mark();
1663    
1664            PsiBuilder.Marker thisReference = mark();
1665            advance(); // THIS_KEYWORD
1666            thisReference.done(REFERENCE_EXPRESSION);
1667    
1668            parseLabelReferenceWithNoWhitespace();
1669    
1670            mark.done(THIS_EXPRESSION);
1671        }
1672    
1673        /*
1674         * "this" ("<" type ">")? label?
1675         */
1676        private void parseSuperExpression() {
1677            assert _at(SUPER_KEYWORD);
1678            PsiBuilder.Marker mark = mark();
1679    
1680            PsiBuilder.Marker superReference = mark();
1681            advance(); // SUPER_KEYWORD
1682            superReference.done(REFERENCE_EXPRESSION);
1683    
1684            if (at(LT)) {
1685                // This may be "super < foo" or "super<foo>", thus the backtracking
1686                PsiBuilder.Marker supertype = mark();
1687    
1688                myBuilder.disableNewlines();
1689                advance(); // LT
1690    
1691                myJetParsing.parseTypeRef();
1692    
1693                if (at(GT)) {
1694                    advance(); // GT
1695                    supertype.drop();
1696                }
1697                else {
1698                    supertype.rollbackTo();
1699                }
1700                myBuilder.restoreNewlinesState();
1701            }
1702            parseLabelReferenceWithNoWhitespace();
1703    
1704            mark.done(SUPER_EXPRESSION);
1705        }
1706    
1707        /*
1708         * valueArguments
1709         *   : "(" (SimpleName "=")? "*"? element{","} ")"
1710         *   ;
1711         */
1712        public void parseValueArgumentList() {
1713            PsiBuilder.Marker list = mark();
1714    
1715            myBuilder.disableNewlines();
1716    
1717            if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) {
1718                if (!at(RPAR)) {
1719                    while (true) {
1720                        while (at(COMMA)) errorAndAdvance("Expecting an argument");
1721                        parseValueArgument();
1722                        if (at(COLON) && lookahead(1) == IDENTIFIER) {
1723                            errorAndAdvance("Unexpected type specification", 2);
1724                        }
1725                        if (!at(COMMA)) break;
1726                        advance(); // COMMA
1727                        if (at(RPAR)) {
1728                            error("Expecting an argument");
1729                            break;
1730                        }
1731                    }
1732                }
1733    
1734                expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW);
1735            }
1736    
1737            myBuilder.restoreNewlinesState();
1738    
1739            list.done(VALUE_ARGUMENT_LIST);
1740        }
1741    
1742        /*
1743         * (SimpleName "=")? "*"? element
1744         */
1745        private void parseValueArgument() {
1746            PsiBuilder.Marker argument = mark();
1747            if (at(IDENTIFIER) && lookahead(1) == EQ) {
1748                PsiBuilder.Marker argName = mark();
1749                PsiBuilder.Marker reference = mark();
1750                advance(); // IDENTIFIER
1751                reference.done(REFERENCE_EXPRESSION);
1752                argName.done(VALUE_ARGUMENT_NAME);
1753                advance(); // EQ
1754            }
1755            if (at(MUL)) {
1756                advance(); // MUL
1757            }
1758            parseExpression();
1759            argument.done(VALUE_ARGUMENT);
1760        }
1761    
1762        /*
1763         * "object" (":" delegationSpecifier{","})? classBody // Cannot make class body optional: foo(object : F, A)
1764         */
1765        public void parseObjectLiteral() {
1766            PsiBuilder.Marker literal = mark();
1767            PsiBuilder.Marker declaration = mark();
1768            myJetParsing.parseObject(NameParsingMode.PROHIBITED, false, LOCAL); // Body is not optional because of foo(object : A, B)
1769            declaration.done(OBJECT_DECLARATION);
1770            literal.done(OBJECT_LITERAL);
1771        }
1772    
1773        private void parseOneTokenExpression(KtNodeType type) {
1774            PsiBuilder.Marker mark = mark();
1775            advance();
1776            mark.done(type);
1777        }
1778    
1779        @Override
1780        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1781            return myJetParsing.create(builder);
1782        }
1783    
1784        private boolean interruptedWithNewLine() {
1785            return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
1786        }
1787    }