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