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