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