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