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