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