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