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