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