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