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