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