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