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