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