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