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.intellij.lang.PsiBuilder;
020import com.intellij.psi.tree.IElementType;
021import com.intellij.psi.tree.TokenSet;
022import org.jetbrains.annotations.Nullable;
023import org.jetbrains.jet.JetNodeType;
024import org.jetbrains.jet.lexer.JetKeywordToken;
025
026import java.util.HashMap;
027import java.util.Map;
028
029import static org.jetbrains.jet.JetNodeTypes.*;
030import static org.jetbrains.jet.lexer.JetTokens.*;
031
032public class JetParsing extends AbstractJetParsing {
033    // TODO: token sets to constants, including derived methods
034    public static final Map<String, IElementType> MODIFIER_KEYWORD_MAP = new HashMap<String, IElementType>();
035    static {
036        for (IElementType softKeyword : MODIFIER_KEYWORDS.getTypes()) {
037            MODIFIER_KEYWORD_MAP.put(((JetKeywordToken) softKeyword).getValue(), softKeyword);
038        }
039    }
040
041    private static final TokenSet TOPLEVEL_OBJECT_FIRST = TokenSet.create(TYPE_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD,
042                FUN_KEYWORD, VAL_KEYWORD, PACKAGE_KEYWORD);
043    private static final TokenSet ENUM_MEMBER_FIRST = TokenSet.create(TYPE_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD,
044                FUN_KEYWORD, VAL_KEYWORD, IDENTIFIER);
045
046    private static final TokenSet CLASS_NAME_RECOVERY_SET = TokenSet.orSet(TokenSet.create(LT, LPAR, COLON, LBRACE), TOPLEVEL_OBJECT_FIRST);
047    private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, LPAR, COLON, LBRACE, GT);
048    private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR);
049    private static final TokenSet NAMESPACE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON);
050    private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON);
051    /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH);
052    private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS);
053    private static final TokenSet VALUE_PARAMETER_FIRST = TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS);
054
055    static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) {
056        JetParsing jetParsing = new JetParsing(builder);
057        jetParsing.myExpressionParsing = new JetExpressionParsing(builder, jetParsing);
058        return jetParsing;
059    }
060
061    private static JetParsing createForByClause(SemanticWhitespaceAwarePsiBuilder builder) {
062        final SemanticWhitespaceAwarePsiBuilderForByClause builderForByClause = new SemanticWhitespaceAwarePsiBuilderForByClause(builder);
063        JetParsing jetParsing = new JetParsing(builderForByClause);
064        jetParsing.myExpressionParsing = new JetExpressionParsing(builderForByClause, jetParsing) {
065            @Override
066            protected boolean parseCallWithClosure() {
067                if (builderForByClause.getStackSize() > 0) {
068                    return super.parseCallWithClosure();
069                }
070                return false;
071            }
072
073            @Override
074            protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
075                return createForByClause(builder);
076            }
077        };
078        return jetParsing;
079    }
080
081    private JetExpressionParsing myExpressionParsing;
082
083    private JetParsing(SemanticWhitespaceAwarePsiBuilder builder) {
084        super(builder);
085    }
086
087    /*
088     * [start] jetlFile
089     *   : preamble toplevelObject[| import]* [eof]
090     *   ;
091     */
092    void parseFile() {
093        PsiBuilder.Marker fileMarker = mark();
094
095        parsePreamble(true);
096
097        parseToplevelDeclarations(false);
098
099        fileMarker.done(JET_FILE);
100    }
101
102    void parseTypeCodeFragment() {
103        PsiBuilder.Marker marker = mark();
104        parseTypeRef();
105
106        while (!eof()) {
107            error("unexpected symbol");
108            advance();
109        }
110
111        marker.done(TYPE_CODE_FRAGMENT);
112    }
113
114    void parseExpressionCodeFragment() {
115        PsiBuilder.Marker marker = mark();
116        myExpressionParsing.parseExpression();
117
118        while (!eof()) {
119            error("unexpected symbol");
120            advance();
121        }
122
123        marker.done(EXPRESSION_CODE_FRAGMENT);
124    }
125
126    void parseScript() {
127        PsiBuilder.Marker fileMarker = mark();
128
129        parsePreamble(false);
130
131        PsiBuilder.Marker scriptMarker = mark();
132        parseImportDirectives();
133
134        PsiBuilder.Marker blockMarker = mark();
135
136        myExpressionParsing.parseStatements();
137
138        blockMarker.done(BLOCK);
139        scriptMarker.done(SCRIPT);
140        fileMarker.done(JET_FILE);
141    }
142
143    /*
144     * toplevelObject[| import]*
145     */
146    private void parseToplevelDeclarations(boolean insideBlock) {
147        while (!eof() && (!insideBlock || !at(RBRACE))) {
148            if (at(IMPORT_KEYWORD)) {
149                parseImportDirective();
150            }
151            else {
152                parseTopLevelObject();
153            }
154        }
155    }
156
157    /*
158     *preamble
159     *  : namespaceHeader? import*
160     *  ;
161     */
162    private void parsePreamble(boolean imports) {
163        /*
164         * namespaceHeader
165         *   : modifiers "namespace" SimpleName{"."} SEMI?
166         *   ;
167         */
168        PsiBuilder.Marker namespaceHeader = mark();
169        PsiBuilder.Marker firstEntry = mark();
170        parseModifierList(MODIFIER_LIST, true);
171
172        if (at(PACKAGE_KEYWORD)) {
173            advance(); // PACKAGE_KEYWORD
174
175
176            parseNamespaceName();
177
178            if (at(LBRACE)) {
179                // Because it's blocked namespace and it will be parsed as one of top level objects
180                firstEntry.rollbackTo();
181                namespaceHeader.done(NAMESPACE_HEADER);
182                return;
183            }
184
185            firstEntry.drop();
186
187            consumeIf(SEMICOLON);
188        }
189        else {
190            firstEntry.rollbackTo();
191        }
192        namespaceHeader.done(NAMESPACE_HEADER);
193
194        if(imports)
195            parseImportDirectives();
196    }
197
198    /* SimpleName{"."} */
199    private void parseNamespaceName() {
200        while (true) {
201            if (myBuilder.newlineBeforeCurrentToken()) {
202                errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", NAMESPACE_NAME_RECOVERY_SET);
203                break;
204            }
205
206            PsiBuilder.Marker nsName = mark();
207            if (expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", NAMESPACE_NAME_RECOVERY_SET)) {
208                nsName.done(REFERENCE_EXPRESSION);
209            }
210            else {
211                nsName.drop();
212            }
213
214            if (at(DOT)) {
215                advance(); // DOT
216            }
217            else {
218                break;
219            }
220        }
221    }
222
223    /*
224     * import
225     *   : "import" ("namespace" ".")? SimpleName{"."} ("." "*" | "as" SimpleName)? SEMI?
226     *   ;
227     */
228    private void parseImportDirective() {
229        assert _at(IMPORT_KEYWORD);
230        PsiBuilder.Marker importDirective = mark();
231        advance(); // IMPORT_KEYWORD
232
233        PsiBuilder.Marker qualifiedName = mark();
234        if (at(PACKAGE_KEYWORD)) {
235            advance(); // PACKAGE_KEYWORD
236            expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER, MUL, SEMICOLON));
237        }
238
239        PsiBuilder.Marker reference = mark();
240        expect(IDENTIFIER, "Expecting qualified name");
241        reference.done(REFERENCE_EXPRESSION);
242
243        while (at(DOT) && lookahead(1) != MUL) {
244            advance(); // DOT
245
246            reference = mark();
247            if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", IMPORT_RECOVERY_SET)) {
248                reference.done(REFERENCE_EXPRESSION);
249            }
250            else {
251                reference.drop();
252            }
253
254            PsiBuilder.Marker precede = qualifiedName.precede();
255            qualifiedName.done(DOT_QUALIFIED_EXPRESSION);
256            qualifiedName = precede;
257        }
258        qualifiedName.drop();
259
260        if (at(DOT)) {
261            advance(); // DOT
262            assert _at(MUL);
263            advance(); // MUL
264            handleUselessRename();
265        }
266        if (at(AS_KEYWORD)) {
267            advance(); // AS_KEYWORD
268            expect(IDENTIFIER, "Expecting identifier", TokenSet.create(SEMICOLON));
269        }
270        consumeIf(SEMICOLON);
271        importDirective.done(IMPORT_DIRECTIVE);
272    }
273
274    private void parseImportDirectives() {
275        // TODO: Duplicate with parsing imports in parseToplevelDeclarations
276        while (at(IMPORT_KEYWORD)) {
277            parseImportDirective();
278        }
279    }
280
281    private void handleUselessRename() {
282        if (at(AS_KEYWORD)) {
283            PsiBuilder.Marker as = mark();
284            advance(); // AS_KEYWORD
285            consumeIf(IDENTIFIER);
286            as.error("Cannot rename a all imported items to one identifier");
287        }
288    }
289
290    /*
291     * toplevelObject
292     *   : namespace
293     *   : class
294     *   : extension
295     *   : function
296     *   : property
297     *   : typedef
298     *   : object
299     *   ;
300     */
301    private void parseTopLevelObject() {
302        PsiBuilder.Marker decl = mark();
303
304        TokenDetector detector = new TokenDetector(ENUM_KEYWORD);
305        parseModifierList(MODIFIER_LIST, detector, true);
306
307        IElementType keywordToken = tt();
308        IElementType declType = null;
309//        if (keywordToken == PACKAGE_KEYWORD) {
310//            declType = parseNamespaceBlock();
311//        }
312//        else
313        if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD) {
314            declType = parseClass(detector.isDetected());
315        }
316        else if (keywordToken == FUN_KEYWORD) {
317            declType = parseFunction();
318        }
319        else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
320            declType = parseProperty();
321        }
322        else if (keywordToken == TYPE_KEYWORD) {
323            declType = parseTypeDef();
324        }
325        else if (keywordToken == OBJECT_KEYWORD) {
326            parseObject(true, true);
327            declType = OBJECT_DECLARATION;
328        }
329
330        if (declType == null) {
331            errorAndAdvance("Expecting package directive or top level declaration");
332            decl.drop();
333        }
334        else {
335            decl.done(declType);
336        }
337    }
338
339    /*
340     * (modifier | attribute)*
341     */
342    boolean parseModifierList(JetNodeType nodeType, boolean allowShortAnnotations) {
343        return parseModifierList(nodeType, null, allowShortAnnotations);
344    }
345
346    /**
347     * (modifier | attribute)*
348     *
349     * Feeds modifiers (not attributes) into the passed consumer, if it is not null
350     */
351    boolean parseModifierList(JetNodeType nodeType, @Nullable Consumer<IElementType> tokenConsumer, boolean allowShortAnnotations) {
352        PsiBuilder.Marker list = mark();
353        boolean empty = true;
354        while (!eof()) {
355            if (atSet(MODIFIER_KEYWORDS)) {
356                if (tokenConsumer != null) tokenConsumer.consume(tt());
357                advance(); // MODIFIER
358            }
359            else if (at(LBRACKET) || (allowShortAnnotations && at(IDENTIFIER))) {
360                parseAnnotation(allowShortAnnotations);
361            }
362            else {
363                break;
364            }
365            empty = false;
366        }
367        if (empty) {
368            list.drop();
369        }
370        else {
371            list.done(nodeType);
372        }
373        return !empty;
374    }
375
376    /*
377     * annotations
378     *   : annotation*
379     *   ;
380     */
381    void parseAnnotations(boolean allowShortAnnotations) {
382        while (true) {
383            if (!(parseAnnotation(allowShortAnnotations))) break;
384        }
385    }
386
387    /*
388     * annotation
389     *   : "[" annotationEntry+ "]"
390     *   : annotationEntry
391     *   ;
392     */
393    private boolean parseAnnotation(boolean allowShortAnnotations) {
394        if (at(LBRACKET)) {
395            PsiBuilder.Marker annotation = mark();
396
397            myBuilder.disableNewlines();
398            advance(); // LBRACKET
399
400            if (!at(IDENTIFIER)) {
401                error("Expecting a list of attributes");
402            }
403            else {
404                parseAnnotationEntry();
405                while (at(COMMA)) {
406                    errorAndAdvance("No commas needed to separate attributes");
407                }
408
409                while (at(IDENTIFIER)) {
410                    parseAnnotationEntry();
411                    while (at(COMMA)) {
412                        errorAndAdvance("No commas needed to separate attributes");
413                    }
414                }
415            }
416
417            expect(RBRACKET, "Expecting ']' to close an attribute annotation");
418            myBuilder.restoreNewlinesState();
419
420            annotation.done(ANNOTATION);
421            return true;
422        }
423        else if (allowShortAnnotations && at(IDENTIFIER)) {
424            parseAnnotationEntry();
425            return true;
426        }
427        return false;
428    }
429
430    /*
431     * annotationEntry
432     *   : SimpleName{"."} typeArguments? valueArguments?
433     *   ;
434     */
435    private void parseAnnotationEntry() {
436        assert _at(IDENTIFIER);
437
438        PsiBuilder.Marker attribute = mark();
439
440        PsiBuilder.Marker reference = mark();
441        PsiBuilder.Marker typeReference = mark();
442        parseUserType();
443        typeReference.done(TYPE_REFERENCE);
444        reference.done(CONSTRUCTOR_CALLEE);
445
446        parseTypeArgumentList();
447
448        if (at(LPAR)) {
449            myExpressionParsing.parseValueArgumentList();
450        }
451        attribute.done(ANNOTATION_ENTRY);
452    }
453
454    /*
455     * class
456     *   : modifiers ("class" | "trait") SimpleName
457     *       typeParameters?
458     *         modifiers ("(" primaryConstructorParameter{","} ")")?
459     *       (":" attributes delegationSpecifier{","})?
460     *       typeConstraints
461     *       (classBody? | enumClassBody)
462     *   ;
463     */
464    IElementType parseClass(boolean enumClass) {
465        assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD);
466        advance(); // CLASS_KEYWORD or TRAIT_KEYWORD
467
468        if (!parseIdeTemplate()) {
469            expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
470        }
471        boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
472
473        PsiBuilder.Marker beforeConstructorModifiers = mark();
474        boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false);
475
476        // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
477        if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON) ) {
478            beforeConstructorModifiers.rollbackTo();
479            return CLASS;
480        }
481
482        // We are still inside a class declaration
483        beforeConstructorModifiers.drop();
484
485        if (at(LPAR)) {
486            parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
487        }
488        else if (hasConstructorModifiers) {
489            // A comprehensive error message for cases like:
490            //    class A private : Foo
491            // or
492            //    class A private {
493            error("Expecting primary constructor parameter list");
494        }
495
496        if (at(COLON)) {
497            advance(); // COLON
498            parseDelegationSpecifierList();
499        }
500
501        parseTypeConstraintsGuarded(typeParametersDeclared);
502
503        if (at(LBRACE)) {
504            if (enumClass) {
505                parseEnumClassBody();
506            }
507            else {
508                parseClassBody();
509            }
510        }
511
512        return CLASS;
513    }
514
515    /*
516     * enumClassBody
517     *   : "{" enumEntry* "}"
518     *   ;
519     */
520    private void parseEnumClassBody() {
521        if (!at(LBRACE)) return;
522
523        PsiBuilder.Marker classBody = mark();
524
525        myBuilder.enableNewlines();
526        advance(); // LBRACE
527
528        if (!parseIdeTemplate()) {
529            while (!eof() && !at(RBRACE)) {
530                PsiBuilder.Marker entryOrMember = mark();
531
532                TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
533                int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
534                TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
535                createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector, false);
536
537                IElementType type;
538                if (at(IDENTIFIER)) {
539                    parseEnumEntry();
540                    type = ENUM_ENTRY;
541                }
542                else {
543                    type = parseMemberDeclarationRest(enumDetector.isDetected());
544                }
545
546                if (type == null) {
547                    errorAndAdvance("Expecting an enum entry or member declaration");
548                    entryOrMember.drop();
549                }
550                else {
551                    entryOrMember.done(type);
552                }
553            }
554        }
555
556        expect(RBRACE, "Expecting '}' to close enum class body");
557        myBuilder.restoreNewlinesState();
558
559        classBody.done(CLASS_BODY);
560    }
561
562    /*
563     * enumEntry
564     *   : modifiers SimpleName (":" initializer{","})? classBody?
565     *   ;
566     */
567    private void parseEnumEntry() {
568        assert _at(IDENTIFIER);
569
570        PsiBuilder.Marker nameAsDeclaration = mark();
571        advance(); // IDENTIFIER
572        nameAsDeclaration.done(OBJECT_DECLARATION_NAME);
573
574        if (at(COLON)) {
575            advance(); // COLON
576
577            parseInitializerList();
578        }
579
580        if (at(LBRACE)) {
581            parseClassBody();
582        }
583
584        consumeIf(SEMICOLON);
585    }
586
587    /*
588     * classBody
589     *   : ("{" memberDeclaration "}")?
590     *   ;
591     */
592    /*package*/ void parseClassBody() {
593        PsiBuilder.Marker body = mark();
594
595        myBuilder.enableNewlines();
596        expect(LBRACE, "Expecting a class body", TokenSet.create(LBRACE));
597
598        if (!parseIdeTemplate()) {
599            while (!eof()) {
600                if (at(RBRACE)) {
601                    break;
602                }
603                parseMemberDeclaration();
604            }
605        }
606        expect(RBRACE, "Missing '}");
607        myBuilder.restoreNewlinesState();
608
609        body.done(CLASS_BODY);
610    }
611
612    /*
613     * memberDeclaration
614     *   : modifiers memberDeclaration'
615     *   ;
616     *
617     * memberDeclaration'
618     *   : classObject
619     *   : constructor
620     *   : function
621     *   : property
622     *   : class
623     *   : extension
624     *   : typedef
625     *   : anonymousInitializer
626     *   : object
627     *   ;
628     */
629    private void parseMemberDeclaration() {
630        PsiBuilder.Marker decl = mark();
631
632        TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
633        parseModifierList(MODIFIER_LIST, enumDetector, true);
634
635        IElementType declType = parseMemberDeclarationRest(enumDetector.isDetected());
636
637        if (declType == null) {
638            errorWithRecovery("Expecting member declaration", TokenSet.create(RBRACE));
639            decl.drop();
640        }
641        else {
642            decl.done(declType);
643        }
644    }
645
646    private IElementType parseMemberDeclarationRest(boolean isEnum) {
647        IElementType keywordToken = tt();
648        IElementType declType = null;
649        if (keywordToken == CLASS_KEYWORD) {
650            if (lookahead(1) == OBJECT_KEYWORD) {
651                declType = parseClassObject();
652            }
653            else {
654                declType = parseClass(isEnum);
655            }
656        }
657        else if (keywordToken == TRAIT_KEYWORD) {
658            declType = parseClass(isEnum);
659        }
660        else if (keywordToken == FUN_KEYWORD) {
661                declType = parseFunction();
662        }
663        else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
664            declType = parseProperty();
665        }
666        else if (keywordToken == TYPE_KEYWORD) {
667            declType = parseTypeDef();
668        }
669        else if (keywordToken == OBJECT_KEYWORD) {
670            parseObject(true, true);
671            declType = OBJECT_DECLARATION;
672        }
673        else if (keywordToken == LBRACE) {
674            parseBlock();
675            declType = ANONYMOUS_INITIALIZER;
676        }
677        return declType;
678    }
679
680    /*
681     * object
682     *   : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
683     *   ;
684     */
685    void parseObject(boolean named, boolean optionalBody) {
686        assert _at(OBJECT_KEYWORD);
687
688        advance(); // OBJECT_KEYWORD
689
690        if (named) {
691            PsiBuilder.Marker propertyDeclaration = mark();
692            if (!parseIdeTemplate()) {
693                expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
694            }
695            propertyDeclaration.done(OBJECT_DECLARATION_NAME);
696        }
697        else {
698            if (at(IDENTIFIER)) {
699                error("An object expression cannot bind a name");
700            }
701        }
702
703        if (optionalBody) {
704            if (at(COLON)) {
705                advance(); // COLON
706                parseDelegationSpecifierList();
707            }
708            if (at(LBRACE)) {
709                parseClassBody();
710            }
711        }
712        else {
713            if (at(LBRACE)) {
714                parseClassBody();
715            }
716            else {
717                expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, PACKAGE_KEYWORD));
718                parseDelegationSpecifierList();
719                parseClassBody();
720            }
721        }
722    }
723
724    /*
725     * initializer{","}
726     */
727    private void parseInitializerList() {
728        PsiBuilder.Marker list = mark();
729        while (true) {
730            if (at(COMMA)) errorAndAdvance("Expecting a this or super constructor call");
731            parseInitializer();
732            if (!at(COMMA)) break;
733            advance(); // COMMA
734        }
735        list.done(INITIALIZER_LIST);
736    }
737
738    /*
739     * initializer
740     *   : attributes "this" valueArguments
741     *   : attributes constructorInvocation // type parameters may (must?) be omitted
742     *   ;
743     */
744    private void parseInitializer() {
745        PsiBuilder.Marker initializer = mark();
746        parseAnnotations(false);
747
748        IElementType type;
749        if (at(THIS_KEYWORD)) {
750            PsiBuilder.Marker mark = mark();
751            advance(); // THIS_KEYWORD
752            mark.done(THIS_CONSTRUCTOR_REFERENCE);
753            type = THIS_CALL;
754        }
755        else if (atSet(TYPE_REF_FIRST)) {
756            PsiBuilder.Marker reference = mark();
757            parseTypeRef();
758            reference.done(CONSTRUCTOR_CALLEE);
759            type = DELEGATOR_SUPER_CALL;
760        }
761        else {
762            errorWithRecovery("Expecting constructor call (this(...)) or supertype initializer", TokenSet.create(LBRACE, COMMA));
763            initializer.drop();
764            return;
765        }
766        myExpressionParsing.parseValueArgumentList();
767
768        initializer.done(type);
769    }
770
771    /*
772     * classObject
773     *   : modifiers "class" object
774     *   ;
775     */
776    private JetNodeType parseClassObject() {
777        assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD;
778
779        advance(); // CLASS_KEYWORD
780
781        PsiBuilder.Marker objectDeclaration = mark();
782        parseObject(false, true);
783        objectDeclaration.done(OBJECT_DECLARATION);
784
785        return CLASS_OBJECT;
786    }
787
788    /*
789     * typedef
790     *   : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
791     *   ;
792     */
793    JetNodeType parseTypeDef() {
794        assert _at(TYPE_KEYWORD);
795
796        advance(); // TYPE_KEYWORD
797
798        expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
799
800        if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
801            parseTypeConstraints();
802        }
803
804        expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
805
806        parseTypeRef();
807
808        consumeIf(SEMICOLON);
809
810        return TYPEDEF;
811    }
812
813    /*
814     * variableDeclarationEntry
815     *   : SimpleName (":" type)?
816     *   ;
817     *
818     * property
819     *   : modifiers ("val" | "var")
820     *       typeParameters? (type "." | annotations)?
821     *       ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
822     *       typeConstraints
823     *       ("by" | "=" expression SEMI?)?
824     *       (getter? setter? | setter? getter?) SEMI?
825     *   ;
826     */
827    private IElementType parseProperty() {
828        return parseProperty(false);
829    }
830
831    public IElementType parseProperty(boolean local) {
832        if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
833            advance(); // VAL_KEYWORD or VAR_KEYWORD
834        }
835        else {
836            errorAndAdvance("Expecting 'val' or 'var'");
837        }
838
839        boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
840
841        TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
842
843        myBuilder.disableJoiningComplexTokens();
844
845        // TODO: extract constant
846        int lastDot = matchTokenStreamPredicate(new LastBefore(
847                new AtSet(DOT, SAFE_ACCESS),
848                new AbstractTokenStreamPredicate() {
849                    @Override
850                    public boolean matching(boolean topLevel) {
851                        if (topLevel && (at(EQ) || at(COLON))) return true;
852                        if (topLevel && at(IDENTIFIER)) {
853                            IElementType lookahead = lookahead(1);
854                            return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
855                        }
856                        return false;
857                    }
858                }));
859
860        PsiBuilder.Marker receiver = mark();
861        parseReceiverType("property", propertyNameFollow, lastDot);
862
863        boolean multiDeclaration = at(LPAR);
864        boolean receiverTypeDeclared = lastDot != -1;
865
866        errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
867
868        if (multiDeclaration) {
869            PsiBuilder.Marker multiDecl = mark();
870            parseMultiDeclarationName(propertyNameFollow);
871            errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
872        }
873        else {
874            parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow);
875        }
876
877        myBuilder.restoreJoiningComplexTokensState();
878
879        if (at(COLON)) {
880            PsiBuilder.Marker type = mark();
881            advance(); // COLON
882            if (!parseIdeTemplate()) {
883                parseTypeRef();
884            }
885            errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
886        }
887
888        parseTypeConstraintsGuarded(typeParametersDeclared);
889
890        if (local) {
891            if (at(BY_KEYWORD)) {
892                parsePropertyDelegate();
893            }
894            else if (at(EQ)) {
895                advance(); // EQ
896                myExpressionParsing.parseExpression();
897                // "val a = 1; b" must not be an infix call of b on "val ...;"
898            }
899        }
900        else {
901            if (at(BY_KEYWORD)) {
902                parsePropertyDelegate();
903                consumeIf(SEMICOLON);
904            }
905            else if (at(EQ)) {
906                advance(); // EQ
907                myExpressionParsing.parseExpression();
908                consumeIf(SEMICOLON);
909            }
910
911            if (parsePropertyGetterOrSetter()) {
912                parsePropertyGetterOrSetter();
913            }
914            if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
915                if (getLastToken() != SEMICOLON) {
916                    errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON));
917                }
918            }
919            else {
920                consumeIf(SEMICOLON);
921            }
922        }
923
924        return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
925    }
926
927    /*
928     * propertyDelegate
929     *   : "by" expression
930     *   ;
931     */
932    private void parsePropertyDelegate() {
933        assert _at(BY_KEYWORD);
934        PsiBuilder.Marker delegate = mark();
935        advance(); // BY_KEYWORD
936        myExpressionParsing.parseExpression();
937        delegate.done(PROPERTY_DELEGATE);
938    }
939
940    /*
941     * (SimpleName (":" type)){","}
942     */
943    public void parseMultiDeclarationName(TokenSet follow) {
944        // Parsing multi-name, e.g.
945        //   val (a, b) = foo()
946        myBuilder.disableNewlines();
947        advance(); // LPAR
948
949        TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
950        if (!atSet(follow)) {
951            while (true) {
952                if (at(COMMA)) {
953                    errorAndAdvance("Expecting a name");
954                }
955                else if (at(RPAR)) {
956                    error("Expecting a name");
957                    break;
958                }
959                PsiBuilder.Marker property = mark();
960                expect(IDENTIFIER, "Expecting a name", recoverySet);
961
962                if (at(COLON)) {
963                    advance(); // COLON
964                    parseTypeRef(follow);
965                }
966                property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
967
968                if (!at(COMMA)) break;
969                advance(); // COMMA
970            }
971        }
972
973        expect(RPAR, "Expecting ')'", follow);
974        myBuilder.restoreNewlinesState();
975    }
976
977    /*
978     * getterOrSetter
979     *   : modifiers ("get" | "set")
980     *   :
981     *        (     "get" "(" ")"
982     *           |
983     *              "set" "(" modifiers parameter ")"
984     *        ) functionBody
985     *   ;
986     */
987    private boolean parsePropertyGetterOrSetter() {
988        PsiBuilder.Marker getterOrSetter = mark();
989
990        parseModifierList(MODIFIER_LIST, false);
991
992        if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
993            getterOrSetter.rollbackTo();
994            return false;
995        }
996
997        boolean setter = at(SET_KEYWORD);
998        advance(); // GET_KEYWORD or SET_KEYWORD
999
1000        if (!at(LPAR)) {
1001            // Account for Jet-114 (val a : int get {...})
1002            TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1003            if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1004                errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1005            }
1006            else {
1007                getterOrSetter.done(PROPERTY_ACCESSOR);
1008                return true;
1009            }
1010        }
1011
1012        myBuilder.disableNewlines();
1013        expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1014        if (setter) {
1015            PsiBuilder.Marker parameterList = mark();
1016            PsiBuilder.Marker setterParameter = mark();
1017            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON));
1018            expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1019
1020            if (at(COLON)) {
1021                advance();  // COLON
1022                parseTypeRef();
1023            }
1024            setterParameter.done(VALUE_PARAMETER);
1025            parameterList.done(VALUE_PARAMETER_LIST);
1026        }
1027        if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON));
1028        expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1029        myBuilder.restoreNewlinesState();
1030
1031        if (at(COLON)) {
1032            advance();
1033
1034            parseTypeRef();
1035        }
1036
1037        parseFunctionBody();
1038
1039        getterOrSetter.done(PROPERTY_ACCESSOR);
1040
1041        return true;
1042    }
1043
1044    /*
1045     * function
1046     *   : modifiers "fun" typeParameters?
1047     *       (type "." | attributes)?
1048     *       SimpleName
1049     *       typeParameters? functionParameters (":" type)?
1050     *       typeConstraints
1051     *       functionBody?
1052     *   ;
1053     */
1054    IElementType parseFunction() {
1055        assert _at(FUN_KEYWORD);
1056
1057        advance(); // FUN_KEYWORD
1058
1059        // Recovery for the case of class A { fun| }
1060        if (at(RBRACE)) {
1061            error("Function body expected");
1062            return FUN;
1063        }
1064
1065        boolean typeParameterListOccurred = false;
1066        if (at(LT)) {
1067            parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
1068            typeParameterListOccurred = true;
1069        }
1070
1071        myBuilder.disableJoiningComplexTokens();
1072        int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true);
1073
1074        TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
1075        parseReceiverType("function", functionNameFollow, lastDot);
1076
1077        parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow);
1078
1079        myBuilder.restoreJoiningComplexTokensState();
1080
1081        TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
1082
1083        if (at(LT)) {
1084            PsiBuilder.Marker error = mark();
1085            parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1086            errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1087            typeParameterListOccurred = true;
1088        }
1089
1090        if (at(LPAR)) {
1091            parseValueParameterList(false, valueParametersFollow);
1092        }
1093        else {
1094            error("Expecting '('");
1095        }
1096
1097        if (at(COLON)) {
1098            advance(); // COLON
1099
1100            if (!parseIdeTemplate()) {
1101                parseTypeRef();
1102            }
1103        }
1104
1105        parseTypeConstraintsGuarded(typeParameterListOccurred);
1106
1107        if (at(SEMICOLON)) {
1108            advance(); // SEMICOLON
1109        }
1110        else if (at(EQ) || at(LBRACE)) {
1111            parseFunctionBody();
1112        }
1113
1114        return FUN;
1115    }
1116
1117    /*
1118     *   (type "." | attributes)?
1119     */
1120    private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) {
1121        if (lastDot == -1) { // There's no explicit receiver type specified
1122            parseAnnotations(false);
1123        }
1124        else {
1125            if (parseIdeTemplate()) {
1126                expect(DOT, "Expecting '.' after receiver template");
1127            }
1128            else {
1129                createTruncatedBuilder(lastDot).parseTypeRef();
1130
1131                if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1132                    advance(); // expectation
1133                }
1134                else {
1135                    errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1136                }
1137            }
1138
1139        }
1140    }
1141
1142    /*
1143     * IDENTIFIER
1144     */
1145    private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow) {
1146        if (!receiverFound) {
1147            if (!parseIdeTemplate()) {
1148                expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow);
1149            }
1150        }
1151        else {
1152            if (!parseIdeTemplate()) {
1153                expect(IDENTIFIER, "Expecting " + title + " name", nameFollow);
1154            }
1155        }
1156    }
1157
1158    /*
1159     * functionBody
1160     *   : block
1161     *   : "=" element
1162     *   ;
1163     */
1164    private void parseFunctionBody() {
1165        if (at(LBRACE)) {
1166            parseBlock();
1167        }
1168        else if (at(EQ)) {
1169            advance(); // EQ
1170            myExpressionParsing.parseExpression();
1171            consumeIf(SEMICOLON);
1172        }
1173        else {
1174            errorAndAdvance("Expecting function body");
1175        }
1176    }
1177
1178    /*
1179     * block
1180     *   : "{" (expressions)* "}"
1181     *   ;
1182     */
1183    void parseBlock() {
1184        PsiBuilder.Marker block = mark();
1185
1186        myBuilder.enableNewlines();
1187        expect(LBRACE, "Expecting '{' to open a block");
1188
1189        myExpressionParsing.parseStatements();
1190
1191        expect(RBRACE, "Expecting '}");
1192        myBuilder.restoreNewlinesState();
1193
1194        block.done(BLOCK);
1195    }
1196
1197    /*
1198     * delegationSpecifier{","}
1199     */
1200    /*package*/ void parseDelegationSpecifierList() {
1201        PsiBuilder.Marker list = mark();
1202
1203        while (true) {
1204            if (at(COMMA)) {
1205                errorAndAdvance("Expecting a delegation specifier");
1206                continue;
1207            }
1208            parseDelegationSpecifier();
1209            if (!at(COMMA)) break;
1210            advance(); // COMMA
1211        }
1212
1213        list.done(DELEGATION_SPECIFIER_LIST);
1214    }
1215
1216    /*
1217     * attributes delegationSpecifier
1218     *
1219     * delegationSpecifier
1220     *   : constructorInvocation // type and constructor arguments
1221     *   : userType
1222     *   : explicitDelegation
1223     *   ;
1224     *
1225     * explicitDelegation
1226     *   : userType "by" element
1227     *   ;
1228     */
1229    private void parseDelegationSpecifier() {
1230        PsiBuilder.Marker delegator = mark();
1231        parseAnnotations(false);
1232
1233        PsiBuilder.Marker reference = mark();
1234        parseTypeRef();
1235
1236        if (at(BY_KEYWORD)) {
1237            reference.drop();
1238            advance(); // BY_KEYWORD
1239            createForByClause(myBuilder).myExpressionParsing.parseExpression();
1240            delegator.done(DELEGATOR_BY);
1241        }
1242        else if (at(LPAR)) {
1243            reference.done(CONSTRUCTOR_CALLEE);
1244            myExpressionParsing.parseValueArgumentList();
1245            delegator.done(DELEGATOR_SUPER_CALL);
1246        }
1247        else {
1248            reference.drop();
1249            delegator.done(DELEGATOR_SUPER_CLASS);
1250        }
1251    }
1252
1253    /*
1254     * typeParameters
1255     *   : ("<" typeParameter{","} ">"
1256     *   ;
1257     */
1258    private boolean parseTypeParameterList(TokenSet recoverySet) {
1259        PsiBuilder.Marker list = mark();
1260        boolean result = false;
1261        if (at(LT)) {
1262
1263            myBuilder.disableNewlines();
1264            advance(); // LT
1265
1266            while (true) {
1267                if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1268                parseTypeParameter();
1269
1270                if (!at(COMMA)) break;
1271                advance(); // COMMA
1272            }
1273
1274            expect(GT, "Missing '>'", recoverySet);
1275            myBuilder.restoreNewlinesState();
1276            result = true;
1277        }
1278        list.done(TYPE_PARAMETER_LIST);
1279        return result;
1280    }
1281
1282    /*
1283     * typeConstraints
1284     *   : ("where" typeConstraint{","})?
1285     *   ;
1286     */
1287    private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1288        PsiBuilder.Marker error = mark();
1289        boolean constraints = parseTypeConstraints();
1290        errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1291    }
1292
1293    private boolean parseTypeConstraints() {
1294        if (at(WHERE_KEYWORD)) {
1295            parseTypeConstraintList();
1296            return true;
1297        }
1298        return false;
1299    }
1300
1301    /*
1302     * typeConstraint{","}
1303     */
1304    private void parseTypeConstraintList() {
1305        assert _at(WHERE_KEYWORD);
1306
1307        advance(); // WHERE_KEYWORD
1308
1309        PsiBuilder.Marker list = mark();
1310
1311        while (true) {
1312            if (at(COMMA)) errorAndAdvance("Type constraint expected");
1313            parseTypeConstraint();
1314            if (!at(COMMA)) break;
1315            advance(); // COMMA
1316        }
1317
1318        list.done(TYPE_CONSTRAINT_LIST);
1319    }
1320
1321    /*
1322     * typeConstraint
1323     *   : attributes SimpleName ":" type
1324     *   : attributes "class" "object" SimpleName ":" type
1325     *   ;
1326     */
1327    private void parseTypeConstraint() {
1328        PsiBuilder.Marker constraint = mark();
1329
1330        parseAnnotations(false);
1331
1332        if (at(CLASS_KEYWORD)) {
1333            advance(); // CLASS_KEYWORD
1334
1335            expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST);
1336
1337        }
1338
1339        PsiBuilder.Marker reference = mark();
1340        if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) {
1341            reference.done(REFERENCE_EXPRESSION);
1342        }
1343        else {
1344            reference.drop();
1345        }
1346
1347        expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
1348
1349        parseTypeRef();
1350
1351        constraint.done(TYPE_CONSTRAINT);
1352    }
1353
1354    /*
1355     * typeParameter
1356     *   : modifiers SimpleName (":" userType)?
1357     *   ;
1358     */
1359    private void parseTypeParameter() {
1360        if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1361            error("Type parameter declaration expected");
1362            return;
1363        }
1364
1365        PsiBuilder.Marker mark = mark();
1366
1367        parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON));
1368
1369        expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1370
1371        if (at(COLON)) {
1372            advance(); // COLON
1373            parseTypeRef();
1374        }
1375
1376        mark.done(TYPE_PARAMETER);
1377
1378    }
1379
1380    /*
1381     * type
1382     *   : attributes typeDescriptor
1383     *
1384     * typeDescriptor
1385     *   : selfType
1386     *   : functionType
1387     *   : userType
1388     *   : tupleType
1389     *   : nullableType
1390     *   ;
1391     *
1392     * nullableType
1393     *   : typeDescriptor "?"
1394     */
1395    void parseTypeRef() {
1396        parseTypeRef(TokenSet.EMPTY);
1397    }
1398
1399    void parseTypeRef(TokenSet extraRecoverySet) {
1400        PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1401        typeRefMarker.done(TYPE_REFERENCE);
1402    }
1403
1404    // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1405    // on expression-indicating symbols or not
1406    private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1407        // Disabling token merge is required for cases like
1408        //    Int?.(Foo) -> Bar
1409        // we don't support this case now
1410//        myBuilder.disableJoiningComplexTokens();
1411        PsiBuilder.Marker typeRefMarker = mark();
1412        parseAnnotations(false);
1413
1414        if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
1415            parseUserType();
1416        }
1417        else if (at(HASH)) {
1418            parseTupleType();
1419        }
1420        else if (at(LPAR)) {
1421            PsiBuilder.Marker functionOrParenthesizedType = mark();
1422
1423            // This may be a function parameter list or just a prenthesized type
1424            advance(); // LPAR
1425            parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1426
1427            if (at(RPAR)) {
1428                advance(); // RPAR
1429                if (at(ARROW)) {
1430                    // It's a function type with one parameter specified
1431                    //    (A) -> B
1432                    functionOrParenthesizedType.rollbackTo();
1433                    parseFunctionType();
1434                }
1435                else {
1436                    // It's a parenthesized type
1437                    //    (A)
1438                    functionOrParenthesizedType.drop();
1439                }
1440            }
1441            else {
1442                // This must be a function type
1443                //   (A, B) -> C
1444                // or
1445                //   (a : A) -> C
1446                functionOrParenthesizedType.rollbackTo();
1447                parseFunctionType();
1448            }
1449
1450        }
1451        else if (at(CAPITALIZED_THIS_KEYWORD)) {
1452            parseSelfType();
1453        }
1454        else {
1455            errorWithRecovery("Type expected",
1456                    TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
1457                                   TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
1458        }
1459
1460        while (at(QUEST)) {
1461            PsiBuilder.Marker precede = typeRefMarker.precede();
1462
1463            advance(); // QUEST
1464            typeRefMarker.done(NULLABLE_TYPE);
1465
1466            typeRefMarker = precede;
1467        }
1468
1469        if (at(DOT)) {
1470            // This is a receiver for a function type
1471            //  A.(B) -> C
1472            //   ^
1473
1474            PsiBuilder.Marker functionType = typeRefMarker.precede();
1475            PsiBuilder.Marker receiverType = typeRefMarker.precede();
1476            typeRefMarker.done(TYPE_REFERENCE);
1477            receiverType.done(FUNCTION_TYPE_RECEIVER);
1478
1479            advance(); // DOT
1480
1481            if (at(LPAR)) {
1482                parseFunctionTypeContents().drop();
1483            }
1484            else {
1485                error("Expecting function type");
1486            }
1487            typeRefMarker = functionType.precede();
1488
1489            functionType.done(FUNCTION_TYPE);
1490        }
1491//        myBuilder.restoreJoiningComplexTokensState();
1492        return typeRefMarker;
1493    }
1494
1495    /*
1496     * userType
1497     *   : ("namespace" ".")? simpleUserType{"."}
1498     *   ;
1499     */
1500    void parseUserType() {
1501        PsiBuilder.Marker userType = mark();
1502
1503        if (at(PACKAGE_KEYWORD)) {
1504            advance(); // PACKAGE_KEYWORD
1505            expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER));
1506        }
1507
1508        PsiBuilder.Marker reference = mark();
1509        while (true) {
1510            if (expect(IDENTIFIER, "Expecting type name", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
1511                reference.done(REFERENCE_EXPRESSION);
1512            }
1513            else {
1514                reference.drop();
1515                break;
1516            }
1517
1518            parseTypeArgumentList();
1519            if (!at(DOT)) {
1520                break;
1521            }
1522            if (lookahead(1) == LPAR) {
1523                // This may be a receiver for a function type
1524                //   Int.(Int) -> Int
1525                break;
1526            }
1527
1528            PsiBuilder.Marker precede = userType.precede();
1529            userType.done(USER_TYPE);
1530            userType = precede;
1531
1532            advance(); // DOT
1533            reference = mark();
1534        }
1535
1536        userType.done(USER_TYPE);
1537    }
1538
1539    /*
1540     * selfType
1541     *   : "This"
1542     *   ;
1543     */
1544    private void parseSelfType() {
1545        assert _at(CAPITALIZED_THIS_KEYWORD);
1546
1547        PsiBuilder.Marker type = mark();
1548        advance(); // CAPITALIZED_THIS_KEYWORD
1549        type.done(SELF_TYPE);
1550    }
1551
1552    /*
1553     *  (optionalProjection type){","}
1554     */
1555    private PsiBuilder.Marker parseTypeArgumentList() {
1556        if (!at(LT)) return null;
1557
1558        PsiBuilder.Marker list = mark();
1559
1560        tryParseTypeArgumentList(TokenSet.EMPTY);
1561
1562        list.done(TYPE_ARGUMENT_LIST);
1563        return list;
1564    }
1565
1566    boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
1567        myBuilder.disableNewlines();
1568        advance(); // LT
1569
1570        while (true) {
1571            PsiBuilder.Marker projection = mark();
1572
1573//            TokenSet lookFor = TokenSet.create(IDENTIFIER);
1574//            TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
1575//            parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
1576            // Currently we do not allow annotations
1577            parseModifierList(MODIFIER_LIST, false);
1578
1579            if (at(MUL)) {
1580                advance(); // MUL
1581            }
1582            else {
1583                parseTypeRef(extraRecoverySet);
1584            }
1585            projection.done(TYPE_PROJECTION);
1586            if (!at(COMMA)) break;
1587            advance(); // COMMA
1588        }
1589
1590        boolean atGT = at(GT);
1591        if (!atGT) {
1592            error("Expecting a '>'");
1593        }
1594        else {
1595            advance(); // GT
1596        }
1597        myBuilder.restoreNewlinesState();
1598        return atGT;
1599    }
1600
1601    private void parseModifierListWithShortAnnotations(JetNodeType modifierList, TokenSet lookFor, TokenSet stopAt) {
1602        int lastId = findLastBefore(lookFor, stopAt, false);
1603        createTruncatedBuilder(lastId).parseModifierList(modifierList, true);
1604    }
1605
1606    /*
1607     * tupleType
1608     *   : "#" "(" type{","}? ")"
1609     *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
1610     *   ;
1611     */
1612    @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1613    private void parseTupleType() {
1614        assert _at(HASH);
1615
1616        PsiBuilder.Marker tuple = mark();
1617
1618        myBuilder.disableNewlines();
1619        advance(); // HASH
1620        consumeIf(LPAR);
1621
1622        if (!at(RPAR)) {
1623            while (true) {
1624                if (at(COLON)) {
1625                    errorAndAdvance("Expecting a name for tuple entry");
1626                }
1627
1628                if (at(IDENTIFIER) && lookahead(1) == COLON) {
1629                    advance(); // IDENTIFIER
1630                    advance(); // COLON
1631                    parseTypeRef();
1632                }
1633                else if (TYPE_REF_FIRST.contains(tt())) {
1634                    parseTypeRef();
1635                }
1636                else {
1637                    error("Type expected");
1638                    break;
1639                }
1640                if (!at(COMMA)) break;
1641                advance(); // COMMA
1642            }
1643        }
1644
1645        consumeIf(RPAR);
1646        myBuilder.restoreNewlinesState();
1647
1648        tuple.error("Tuples are not supported. Use data classes instead.");
1649    }
1650
1651    /*
1652     * functionType
1653     *   : "(" (parameter | modifiers type){","}? ")" "->" type?
1654     *   ;
1655     */
1656    private void parseFunctionType() {
1657        parseFunctionTypeContents().done(FUNCTION_TYPE);
1658    }
1659
1660    private PsiBuilder.Marker parseFunctionTypeContents() {
1661        assert _at(LPAR) : tt();
1662        PsiBuilder.Marker functionType = mark();
1663
1664//        advance(); // LPAR
1665//
1666//        int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false);
1667//        if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
1668//            TODO : -1 is a hack?
1669//            createTruncatedBuilder(lastLPar - 1).parseTypeRef();
1670//            advance(); // DOT
1671//        }
1672
1673        parseValueParameterList(true, TokenSet.EMPTY);
1674
1675//        if (at(COLON)) {
1676//            advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
1677
1678        expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
1679        parseTypeRef();
1680//        }
1681
1682        return functionType;//.done(FUNCTION_TYPE);
1683    }
1684
1685    /*
1686     * functionParameters
1687     *   : "(" functionParameter{","}? ")" // default values
1688     *   ;
1689     *
1690     * functionParameter
1691     *   : modifiers functionParameterRest
1692     *   ;
1693     *
1694     * functionParameterRest
1695     *   : parameter ("=" element)?
1696     *   ;
1697     */
1698    void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
1699        assert _at(LPAR);
1700        PsiBuilder.Marker parameters = mark();
1701
1702        myBuilder.disableNewlines();
1703        advance(); // LPAR
1704
1705        if (!parseIdeTemplate()) {
1706            if (!at(RPAR) && !atSet(recoverySet)) {
1707                while (true) {
1708                    if (at(COMMA)) {
1709                        errorAndAdvance("Expecting a parameter declaration");
1710                    }
1711                    else if (at(RPAR)) {
1712                        error("Expecting a parameter declaration");
1713                        break;
1714                    }
1715                    if (isFunctionTypeContents) {
1716                        if (!tryParseValueParameter()) {
1717                            PsiBuilder.Marker valueParameter = mark();
1718                            parseModifierList(MODIFIER_LIST, false); // lazy, out, ref
1719                            parseTypeRef();
1720                            valueParameter.done(VALUE_PARAMETER);
1721                        }
1722                    }
1723                    else {
1724                        parseValueParameter();
1725                    }
1726                    if (at(COMMA)) {
1727                        advance(); // COMMA
1728                    }
1729                    else if (!atSet(VALUE_PARAMETER_FIRST)) break;
1730                }
1731            }
1732        }
1733
1734        expect(RPAR, "Expecting ')'", recoverySet);
1735        myBuilder.restoreNewlinesState();
1736
1737        parameters.done(VALUE_PARAMETER_LIST);
1738    }
1739
1740    /*
1741     * functionParameter
1742     *   : modifiers ("val" | "var")? parameter ("=" element)?
1743     *   ;
1744     */
1745    private boolean tryParseValueParameter() {
1746        return parseValueParameter(true);
1747    }
1748
1749    public void parseValueParameter() {
1750        parseValueParameter(false);
1751    }
1752
1753    private boolean parseValueParameter(boolean rollbackOnFailure) {
1754        PsiBuilder.Marker parameter = mark();
1755
1756        parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON));
1757
1758        if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
1759            advance(); // VAR_KEYWORD | VAL_KEYWORD
1760        }
1761
1762        if (!parseFunctionParameterRest() && rollbackOnFailure) {
1763            parameter.rollbackTo();
1764            return false;
1765        }
1766
1767        parameter.done(VALUE_PARAMETER);
1768        return true;
1769    }
1770
1771    /*
1772     * functionParameterRest
1773     *   : parameter ("=" element)?
1774     *   ;
1775     */
1776    private boolean parseFunctionParameterRest() {
1777        boolean noErrors = true;
1778
1779        // Recovery for the case 'fun foo(Array<String>) {}'
1780        if (at(IDENTIFIER) && lookahead(1) == LT) {
1781            error("Parameter name expected");
1782            parseTypeRef();
1783            noErrors = false;
1784        }
1785        else {
1786            expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
1787
1788            if (at(COLON)) {
1789                advance(); // COLON
1790                parseTypeRef();
1791            }
1792            else {
1793                errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
1794                noErrors = false;
1795            }
1796        }
1797
1798        if (at(EQ)) {
1799            advance(); // EQ
1800            myExpressionParsing.parseExpression();
1801        }
1802
1803        return noErrors;
1804    }
1805
1806    /*
1807    * "<#<" expression ">#>"
1808    */
1809    boolean parseIdeTemplate() {
1810        @Nullable JetNodeType nodeType = IDE_TEMPLATE_EXPRESSION;
1811        if (at(IDE_TEMPLATE_START)) {
1812            PsiBuilder.Marker mark = null;
1813            if (nodeType != null) {
1814                mark = mark();
1815            }
1816            advance();
1817            expect(IDENTIFIER, "Expecting identifier inside template");
1818            expect(IDE_TEMPLATE_END, "Expecting IDE template end after identifier");
1819            if (nodeType != null) {
1820                mark.done(nodeType);
1821            }
1822            return true;
1823        }
1824        else {
1825            return false;
1826        }
1827    }
1828
1829    @Override
1830    protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1831        return createForTopLevel(builder);
1832    }
1833
1834    /*package*/ static class TokenDetector implements Consumer<IElementType> {
1835
1836        private boolean detected = false;
1837        private final TokenSet tokens;
1838
1839        public TokenDetector(JetKeywordToken token) {
1840            this.tokens = TokenSet.create(token);
1841        }
1842
1843        @Override
1844        public void consume(IElementType item) {
1845            if (tokens.contains(item)) {
1846                detected = true;
1847            }
1848        }
1849
1850        public boolean isDetected() {
1851            return detected;
1852        }
1853    }
1854}