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);
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                }
892                else {
893                    // if we're on LPAR it's probably start of value arguments list
894                    if (!at(LPAR)) {
895                        advance(); // wrong delegation call keyword?
896                    }
897                    error("Expecting a 'this' or 'super' constructor call");
898                }
899    
900                myExpressionParsing.parseValueArgumentList();
901    
902                delegationCall.done(CONSTRUCTOR_DELEGATION_CALL);
903            }
904            else {
905                // empty constructor delegation call
906                PsiBuilder.Marker emptyDelegationCall = mark();
907                mark().done(CONSTRUCTOR_DELEGATION_REFERENCE);
908                emptyDelegationCall.done(CONSTRUCTOR_DELEGATION_CALL);
909            }
910    
911            parseBlock();
912        }
913    
914        private void parseThisOrSuper() {
915            assert _at(THIS_KEYWORD) || _at(SUPER_KEYWORD);
916            PsiBuilder.Marker mark = mark();
917    
918            advance(); // THIS_KEYWORD | SUPER_KEYWORD
919    
920            mark.done(CONSTRUCTOR_DELEGATION_REFERENCE);
921        }
922    
923        /*
924         * initializer{","}
925         */
926        private void parseInitializerList() {
927            PsiBuilder.Marker list = mark();
928            while (true) {
929                if (at(COMMA)) errorAndAdvance("Expecting a this or super constructor call");
930                parseInitializer();
931                if (!at(COMMA)) break;
932                advance(); // COMMA
933            }
934            list.done(INITIALIZER_LIST);
935        }
936    
937        /*
938         * initializer
939         *   : annotations constructorInvocation // type parameters may (must?) be omitted
940         *   ;
941         */
942        private void parseInitializer() {
943            PsiBuilder.Marker initializer = mark();
944            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
945    
946            IElementType type;
947            if (atSet(TYPE_REF_FIRST)) {
948                PsiBuilder.Marker reference = mark();
949                parseTypeRef();
950                reference.done(CONSTRUCTOR_CALLEE);
951                type = DELEGATOR_SUPER_CALL;
952            }
953            else {
954                errorWithRecovery("Expecting constructor call (<class-name>(...))",
955                                  TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(RBRACE, LBRACE, COMMA, SEMICOLON)));
956                initializer.drop();
957                return;
958            }
959            myExpressionParsing.parseValueArgumentList();
960    
961            initializer.done(type);
962        }
963    
964        /*
965         * companionObject
966         *   : modifiers "class" object
967         *   ;
968         */
969        private IElementType parseDeprecatedClassObject() {
970            assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD;
971            advance(); // CLASS_KEYWORD
972            parseObject(NameParsingMode.ALLOWED, true);
973            return OBJECT_DECLARATION;
974        }
975    
976        /*
977         * typeAlias
978         *   : modifiers "typealias" SimpleName (typeParameters typeConstraints)? "=" type
979         *   ;
980         */
981        JetNodeType parseTypeAlias() {
982            assert _at(TYPE_ALIAS_KEYWORD);
983    
984            advance(); // TYPE_ALIAS_KEYWORD
985    
986            expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
987    
988            if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
989                parseTypeConstraints();
990            }
991    
992            expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
993    
994            parseTypeRef();
995    
996            consumeIf(SEMICOLON);
997    
998            return TYPEDEF;
999        }
1000    
1001        /*
1002         * variableDeclarationEntry
1003         *   : SimpleName (":" type)?
1004         *   ;
1005         *
1006         * property
1007         *   : modifiers ("val" | "var")
1008         *       typeParameters? (type "." | annotations)?
1009         *       ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
1010         *       typeConstraints
1011         *       ("by" | "=" expression SEMI?)?
1012         *       (getter? setter? | setter? getter?) SEMI?
1013         *   ;
1014         */
1015        private IElementType parseProperty() {
1016            return parseProperty(false);
1017        }
1018    
1019        public IElementType parseProperty(boolean local) {
1020            if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
1021                advance(); // VAL_KEYWORD or VAR_KEYWORD
1022            }
1023            else {
1024                errorAndAdvance("Expecting 'val' or 'var'");
1025            }
1026    
1027            boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
1028    
1029            TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
1030    
1031            myBuilder.disableJoiningComplexTokens();
1032    
1033            PsiBuilder.Marker receiver = mark();
1034            boolean receiverTypeDeclared = parseReceiverType("property", propertyNameFollow);
1035    
1036            boolean multiDeclaration = at(LPAR);
1037    
1038            errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
1039    
1040            if (multiDeclaration) {
1041                PsiBuilder.Marker multiDecl = mark();
1042                parseMultiDeclarationName(propertyNameFollow);
1043                errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
1044            }
1045            else {
1046                parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow, /*nameRequired = */ false);
1047            }
1048    
1049            myBuilder.restoreJoiningComplexTokensState();
1050    
1051            if (at(COLON)) {
1052                PsiBuilder.Marker type = mark();
1053                advance(); // COLON
1054                parseTypeRef();
1055                errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
1056            }
1057    
1058            parseTypeConstraintsGuarded(typeParametersDeclared);
1059    
1060            if (local) {
1061                if (at(BY_KEYWORD)) {
1062                    parsePropertyDelegate();
1063                }
1064                else if (at(EQ)) {
1065                    advance(); // EQ
1066                    myExpressionParsing.parseExpression();
1067                    // "val a = 1; b" must not be an infix call of b on "val ...;"
1068                }
1069            }
1070            else {
1071                if (at(BY_KEYWORD)) {
1072                    parsePropertyDelegate();
1073                    consumeIf(SEMICOLON);
1074                }
1075                else if (at(EQ)) {
1076                    advance(); // EQ
1077                    myExpressionParsing.parseExpression();
1078                    consumeIf(SEMICOLON);
1079                }
1080    
1081                if (parsePropertyGetterOrSetter()) {
1082                    parsePropertyGetterOrSetter();
1083                }
1084                if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
1085                    if (getLastToken() != SEMICOLON) {
1086                        errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON));
1087                    }
1088                }
1089                else {
1090                    consumeIf(SEMICOLON);
1091                }
1092            }
1093    
1094            return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
1095        }
1096    
1097        /*
1098         * propertyDelegate
1099         *   : "by" expression
1100         *   ;
1101         */
1102        private void parsePropertyDelegate() {
1103            assert _at(BY_KEYWORD);
1104            PsiBuilder.Marker delegate = mark();
1105            advance(); // BY_KEYWORD
1106            myExpressionParsing.parseExpression();
1107            delegate.done(PROPERTY_DELEGATE);
1108        }
1109    
1110        /*
1111         * (SimpleName (":" type)){","}
1112         */
1113        public void parseMultiDeclarationName(TokenSet follow) {
1114            // Parsing multi-name, e.g.
1115            //   val (a, b) = foo()
1116            myBuilder.disableNewlines();
1117            advance(); // LPAR
1118    
1119            TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
1120            if (!atSet(follow)) {
1121                while (true) {
1122                    if (at(COMMA)) {
1123                        errorAndAdvance("Expecting a name");
1124                    }
1125                    else if (at(RPAR)) {
1126                        error("Expecting a name");
1127                        break;
1128                    }
1129                    PsiBuilder.Marker property = mark();
1130                    expect(IDENTIFIER, "Expecting a name", recoverySet);
1131    
1132                    if (at(COLON)) {
1133                        advance(); // COLON
1134                        parseTypeRef(follow);
1135                    }
1136                    property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
1137    
1138                    if (!at(COMMA)) break;
1139                    advance(); // COMMA
1140                }
1141            }
1142    
1143            expect(RPAR, "Expecting ')'", follow);
1144            myBuilder.restoreNewlinesState();
1145        }
1146    
1147        /*
1148         * getterOrSetter
1149         *   : modifiers ("get" | "set")
1150         *   :
1151         *        (     "get" "(" ")"
1152         *           |
1153         *              "set" "(" modifiers parameter ")"
1154         *        ) functionBody
1155         *   ;
1156         */
1157        private boolean parsePropertyGetterOrSetter() {
1158            PsiBuilder.Marker getterOrSetter = mark();
1159    
1160            parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1161    
1162            if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
1163                getterOrSetter.rollbackTo();
1164                return false;
1165            }
1166    
1167            boolean setter = at(SET_KEYWORD);
1168            advance(); // GET_KEYWORD or SET_KEYWORD
1169    
1170            if (!at(LPAR)) {
1171                // Account for Jet-114 (val a : int get {...})
1172                TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1173                if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1174                    errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1175                }
1176                else {
1177                    closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false);
1178                    return true;
1179                }
1180            }
1181    
1182            myBuilder.disableNewlines();
1183            expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1184            if (setter) {
1185                PsiBuilder.Marker parameterList = mark();
1186                PsiBuilder.Marker setterParameter = mark();
1187                parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON));
1188                expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1189    
1190                if (at(COLON)) {
1191                    advance();  // COLON
1192                    parseTypeRef();
1193                }
1194                setterParameter.done(VALUE_PARAMETER);
1195                parameterList.done(VALUE_PARAMETER_LIST);
1196            }
1197            if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON));
1198            expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1199            myBuilder.restoreNewlinesState();
1200    
1201            if (at(COLON)) {
1202                advance();
1203    
1204                parseTypeRef();
1205            }
1206    
1207            parseFunctionBody();
1208    
1209            closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false);
1210    
1211            return true;
1212        }
1213    
1214        /*
1215         * function
1216         *   : modifiers "fun" typeParameters?
1217         *       (type "." | annotations)?
1218         *       SimpleName
1219         *       typeParameters? functionParameters (":" type)?
1220         *       typeConstraints
1221         *       functionBody?
1222         *   ;
1223         */
1224        IElementType parseFunction() {
1225            assert _at(FUN_KEYWORD);
1226    
1227            advance(); // FUN_KEYWORD
1228    
1229            // Recovery for the case of class A { fun| }
1230            if (at(RBRACE)) {
1231                error("Function body expected");
1232                return FUN;
1233            }
1234    
1235            boolean typeParameterListOccurred = false;
1236            if (at(LT)) {
1237                parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
1238                typeParameterListOccurred = true;
1239            }
1240    
1241            myBuilder.disableJoiningComplexTokens();
1242    
1243            TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ);
1244            boolean receiverFound = parseReceiverType("function", functionNameFollow);
1245    
1246            // function as expression has no name
1247            parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ true);
1248    
1249            myBuilder.restoreJoiningComplexTokensState();
1250    
1251            TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
1252    
1253            if (at(LT)) {
1254                PsiBuilder.Marker error = mark();
1255                parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1256                errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1257                typeParameterListOccurred = true;
1258            }
1259    
1260            if (at(LPAR)) {
1261                parseValueParameterList(false, /* typeRequired  = */ false, valueParametersFollow);
1262            }
1263            else {
1264                error("Expecting '('");
1265            }
1266    
1267            if (at(COLON)) {
1268                advance(); // COLON
1269    
1270                parseTypeRef();
1271            }
1272    
1273            parseTypeConstraintsGuarded(typeParameterListOccurred);
1274    
1275            if (at(SEMICOLON)) {
1276                advance(); // SEMICOLON
1277            }
1278            else if (at(EQ) || at(LBRACE)) {
1279                parseFunctionBody();
1280            }
1281    
1282            return FUN;
1283        }
1284    
1285        /*
1286         *   (type "." | annotations)?
1287         */
1288        private boolean parseReceiverType(String title, TokenSet nameFollow) {
1289            PsiBuilder.Marker annotations = mark();
1290            boolean annotationsPresent = parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1291            int lastDot = lastDotAfterReceiver();
1292            boolean receiverPresent = lastDot != -1;
1293            if (annotationsPresent) {
1294                if (receiverPresent) {
1295                    annotations.rollbackTo();
1296                }
1297                else {
1298                    annotations.error("Annotations are not allowed in this position");
1299                }
1300            }
1301            else {
1302                annotations.drop();
1303            }
1304    
1305            if (!receiverPresent) return false;
1306    
1307            createTruncatedBuilder(lastDot).parseTypeRef();
1308    
1309            if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1310                advance(); // expectation
1311            }
1312            else {
1313                errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1314            }
1315            return true;
1316        }
1317    
1318        private int lastDotAfterReceiver() {
1319            if (at(LPAR)) {
1320                return matchTokenStreamPredicate(
1321                        new FirstBefore(
1322                                new AtSet(RECEIVER_TYPE_TERMINATORS),
1323                                new AbstractTokenStreamPredicate() {
1324                                    @Override
1325                                    public boolean matching(boolean topLevel) {
1326                                        if (topLevel && definitelyOutOfReceiver()) {
1327                                            return true;
1328                                        }
1329                                        return topLevel && !at(QUEST) && !at(LPAR) && !at(RPAR);
1330                                    }
1331                                }
1332                        ));
1333            }
1334            else {
1335                return matchTokenStreamPredicate(
1336                        new LastBefore(
1337                                new AtSet(RECEIVER_TYPE_TERMINATORS),
1338                                new AbstractTokenStreamPredicate() {
1339                                    @Override
1340                                    public boolean matching(boolean topLevel) {
1341                                        if (topLevel && (definitelyOutOfReceiver() || at(LPAR))) return true;
1342                                        if (topLevel && at(IDENTIFIER)) {
1343                                            IElementType lookahead = lookahead(1);
1344                                            return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
1345                                        }
1346                                        return false;
1347                                    }
1348                                }));
1349            }
1350        }
1351    
1352        private boolean definitelyOutOfReceiver() {
1353            return atSet(EQ, COLON, LBRACE, BY_KEYWORD) || atSet(TOPLEVEL_OBJECT_FIRST);
1354        }
1355    
1356        /*
1357         * IDENTIFIER
1358         */
1359        private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
1360            if (nameRequired && atSet(nameFollow)) return; // no name
1361    
1362            if (!receiverFound) {
1363                expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow);
1364            }
1365            else {
1366                expect(IDENTIFIER, "Expecting " + title + " name", nameFollow);
1367            }
1368        }
1369    
1370        /*
1371         * functionBody
1372         *   : block
1373         *   : "=" element
1374         *   ;
1375         */
1376        private void parseFunctionBody() {
1377            if (at(LBRACE)) {
1378                parseBlock();
1379            }
1380            else if (at(EQ)) {
1381                advance(); // EQ
1382                myExpressionParsing.parseExpression();
1383                consumeIf(SEMICOLON);
1384            }
1385            else {
1386                errorAndAdvance("Expecting function body");
1387            }
1388        }
1389    
1390        /*
1391         * block
1392         *   : "{" (expressions)* "}"
1393         *   ;
1394         */
1395        void parseBlock() {
1396            PsiBuilder.Marker block = mark();
1397    
1398            myBuilder.enableNewlines();
1399            expect(LBRACE, "Expecting '{' to open a block");
1400    
1401            myExpressionParsing.parseStatements();
1402    
1403            expect(RBRACE, "Expecting '}'");
1404            myBuilder.restoreNewlinesState();
1405    
1406            block.done(BLOCK);
1407        }
1408    
1409        /*
1410         * delegationSpecifier{","}
1411         */
1412        /*package*/ void parseDelegationSpecifierList() {
1413            PsiBuilder.Marker list = mark();
1414    
1415            while (true) {
1416                if (at(COMMA)) {
1417                    errorAndAdvance("Expecting a delegation specifier");
1418                    continue;
1419                }
1420                parseDelegationSpecifier();
1421                if (!at(COMMA)) break;
1422                advance(); // COMMA
1423            }
1424    
1425            list.done(DELEGATION_SPECIFIER_LIST);
1426        }
1427    
1428        /*
1429         * annotations delegationSpecifier
1430         *
1431         * delegationSpecifier
1432         *   : constructorInvocation // type and constructor arguments
1433         *   : userType
1434         *   : explicitDelegation
1435         *   ;
1436         *
1437         * explicitDelegation
1438         *   : userType "by" element
1439         *   ;
1440         */
1441        private void parseDelegationSpecifier() {
1442            PsiBuilder.Marker delegator = mark();
1443            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1444    
1445            PsiBuilder.Marker reference = mark();
1446            parseTypeRef();
1447    
1448            if (at(BY_KEYWORD)) {
1449                reference.drop();
1450                advance(); // BY_KEYWORD
1451                createForByClause(myBuilder).myExpressionParsing.parseExpression();
1452                delegator.done(DELEGATOR_BY);
1453            }
1454            else if (at(LPAR)) {
1455                reference.done(CONSTRUCTOR_CALLEE);
1456                myExpressionParsing.parseValueArgumentList();
1457                delegator.done(DELEGATOR_SUPER_CALL);
1458            }
1459            else {
1460                reference.drop();
1461                delegator.done(DELEGATOR_SUPER_CLASS);
1462            }
1463        }
1464    
1465        /*
1466         * typeParameters
1467         *   : ("<" typeParameter{","} ">"
1468         *   ;
1469         */
1470        private boolean parseTypeParameterList(TokenSet recoverySet) {
1471            boolean result = false;
1472            if (at(LT)) {
1473                PsiBuilder.Marker list = mark();
1474    
1475                myBuilder.disableNewlines();
1476                advance(); // LT
1477    
1478                while (true) {
1479                    if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1480                    parseTypeParameter();
1481    
1482                    if (!at(COMMA)) break;
1483                    advance(); // COMMA
1484                }
1485    
1486                expect(GT, "Missing '>'", recoverySet);
1487                myBuilder.restoreNewlinesState();
1488                result = true;
1489    
1490                list.done(TYPE_PARAMETER_LIST);
1491            }
1492            return result;
1493        }
1494    
1495        /*
1496         * typeConstraints
1497         *   : ("where" typeConstraint{","})?
1498         *   ;
1499         */
1500        private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1501            PsiBuilder.Marker error = mark();
1502            boolean constraints = parseTypeConstraints();
1503            errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1504        }
1505    
1506        private boolean parseTypeConstraints() {
1507            if (at(WHERE_KEYWORD)) {
1508                parseTypeConstraintList();
1509                return true;
1510            }
1511            return false;
1512        }
1513    
1514        /*
1515         * typeConstraint{","}
1516         */
1517        private void parseTypeConstraintList() {
1518            assert _at(WHERE_KEYWORD);
1519    
1520            advance(); // WHERE_KEYWORD
1521    
1522            PsiBuilder.Marker list = mark();
1523    
1524            while (true) {
1525                if (at(COMMA)) errorAndAdvance("Type constraint expected");
1526                parseTypeConstraint();
1527                if (!at(COMMA)) break;
1528                advance(); // COMMA
1529            }
1530    
1531            list.done(TYPE_CONSTRAINT_LIST);
1532        }
1533    
1534        /*
1535         * typeConstraint
1536         *   : annotations SimpleName ":" type
1537         *   : annotations "class" "object" SimpleName ":" type
1538         *   ;
1539         */
1540        private void parseTypeConstraint() {
1541            PsiBuilder.Marker constraint = mark();
1542    
1543            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1544    
1545            if (at(CLASS_KEYWORD)) {
1546                advance(); // CLASS_KEYWORD
1547    
1548                expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST);
1549    
1550            }
1551    
1552            PsiBuilder.Marker reference = mark();
1553            if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) {
1554                reference.done(REFERENCE_EXPRESSION);
1555            }
1556            else {
1557                reference.drop();
1558            }
1559    
1560            expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
1561    
1562            parseTypeRef();
1563    
1564            constraint.done(TYPE_CONSTRAINT);
1565        }
1566    
1567        /*
1568         * typeParameter
1569         *   : modifiers SimpleName (":" userType)?
1570         *   ;
1571         */
1572        private void parseTypeParameter() {
1573            if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1574                error("Type parameter declaration expected");
1575                return;
1576            }
1577    
1578            PsiBuilder.Marker mark = mark();
1579    
1580            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON));
1581    
1582            expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1583    
1584            if (at(COLON)) {
1585                advance(); // COLON
1586                parseTypeRef();
1587            }
1588    
1589            mark.done(TYPE_PARAMETER);
1590    
1591        }
1592    
1593        /*
1594         * type
1595         *   : annotations typeDescriptor
1596         *
1597         * typeDescriptor
1598         *   : selfType
1599         *   : functionType
1600         *   : userType
1601         *   : tupleType
1602         *   : nullableType
1603         *   : "dynamic"
1604         *   ;
1605         *
1606         * nullableType
1607         *   : typeDescriptor "?"
1608         */
1609        void parseTypeRef() {
1610            parseTypeRef(TokenSet.EMPTY);
1611        }
1612    
1613        void parseTypeRef(TokenSet extraRecoverySet) {
1614            PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1615            typeRefMarker.done(TYPE_REFERENCE);
1616        }
1617    
1618        // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1619        // on expression-indicating symbols or not
1620        private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1621            // Disabling token merge is required for cases like
1622            //    Int?.(Foo) -> Bar
1623            // we don't support this case now
1624    //        myBuilder.disableJoiningComplexTokens();
1625            PsiBuilder.Marker typeRefMarker = mark();
1626            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1627    
1628            IElementType lookahead = lookahead(1);
1629            IElementType lookahead2 = lookahead(2);
1630            if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
1631                PsiBuilder.Marker dynamicType = mark();
1632                advance(); // DYNAMIC_KEYWORD
1633                dynamicType.done(DYNAMIC_TYPE);
1634            }
1635            else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
1636                parseUserType();
1637            }
1638            else if (at(HASH)) {
1639                parseTupleType();
1640            }
1641            else if (at(LPAR)) {
1642                PsiBuilder.Marker functionOrParenthesizedType = mark();
1643    
1644                // This may be a function parameter list or just a prenthesized type
1645                advance(); // LPAR
1646                parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1647    
1648                if (at(RPAR)) {
1649                    advance(); // RPAR
1650                    if (at(ARROW)) {
1651                        // It's a function type with one parameter specified
1652                        //    (A) -> B
1653                        functionOrParenthesizedType.rollbackTo();
1654                        parseFunctionType();
1655                    }
1656                    else {
1657                        // It's a parenthesized type
1658                        //    (A)
1659                        functionOrParenthesizedType.drop();
1660                    }
1661                }
1662                else {
1663                    // This must be a function type
1664                    //   (A, B) -> C
1665                    // or
1666                    //   (a : A) -> C
1667                    functionOrParenthesizedType.rollbackTo();
1668                    parseFunctionType();
1669                }
1670    
1671            }
1672            else if (at(CAPITALIZED_THIS_KEYWORD)) {
1673                parseSelfType();
1674            }
1675            else {
1676                errorWithRecovery("Type expected",
1677                        TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
1678                                       TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
1679            }
1680    
1681            typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
1682    
1683            if (at(DOT)) {
1684                // This is a receiver for a function type
1685                //  A.(B) -> C
1686                //   ^
1687    
1688                PsiBuilder.Marker functionType = typeRefMarker.precede();
1689                PsiBuilder.Marker receiverType = typeRefMarker.precede();
1690                typeRefMarker.done(TYPE_REFERENCE);
1691                receiverType.done(FUNCTION_TYPE_RECEIVER);
1692    
1693                advance(); // DOT
1694    
1695                if (at(LPAR)) {
1696                    parseFunctionTypeContents().drop();
1697                }
1698                else {
1699                    error("Expecting function type");
1700                }
1701                typeRefMarker = functionType.precede();
1702    
1703                functionType.done(FUNCTION_TYPE);
1704            }
1705    //        myBuilder.restoreJoiningComplexTokensState();
1706            return typeRefMarker;
1707        }
1708    
1709        @NotNull
1710        PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
1711            while (at(QUEST)) {
1712                PsiBuilder.Marker precede = typeRefMarker.precede();
1713                advance(); // QUEST
1714                typeRefMarker.done(NULLABLE_TYPE);
1715                typeRefMarker = precede;
1716            }
1717            return typeRefMarker;
1718        }
1719    
1720        /*
1721         * userType
1722         *   : ("package" ".")? simpleUserType{"."}
1723         *   ;
1724         *
1725         *   recovers on platform types:
1726         *    - Foo!
1727         *    - (Mutable)List<Foo>!
1728         *    - Array<(out) Foo>!
1729         */
1730        void parseUserType() {
1731            PsiBuilder.Marker userType = mark();
1732    
1733            if (at(PACKAGE_KEYWORD)) {
1734                advance(); // PACKAGE_KEYWORD
1735                expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER));
1736            }
1737    
1738            PsiBuilder.Marker reference = mark();
1739            while (true) {
1740                recoverOnParenthesizedWordForPlatformTypes(0, "Mutable", true);
1741    
1742                if (expect(IDENTIFIER, "Expecting type name",
1743                           TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
1744                    reference.done(REFERENCE_EXPRESSION);
1745                }
1746                else {
1747                    reference.drop();
1748                    break;
1749                }
1750    
1751                parseTypeArgumentList();
1752    
1753                recoverOnPlatformTypeSuffix();
1754    
1755                if (!at(DOT)) {
1756                    break;
1757                }
1758                if (lookahead(1) == LPAR && !atParenthesizedMutableForPlatformTypes(1)) {
1759                    // This may be a receiver for a function type
1760                    //   Int.(Int) -> Int
1761                    break;
1762                }
1763    
1764                PsiBuilder.Marker precede = userType.precede();
1765                userType.done(USER_TYPE);
1766                userType = precede;
1767    
1768                advance(); // DOT
1769                reference = mark();
1770            }
1771    
1772            userType.done(USER_TYPE);
1773        }
1774    
1775        private boolean atParenthesizedMutableForPlatformTypes(int offset) {
1776            return recoverOnParenthesizedWordForPlatformTypes(offset, "Mutable", false);
1777        }
1778    
1779        private boolean recoverOnParenthesizedWordForPlatformTypes(int offset, String word, boolean consume) {
1780            // Array<(out) Foo>! or (Mutable)List<Bar>!
1781            if (lookahead(offset) == LPAR && lookahead(offset + 1) == IDENTIFIER && lookahead(offset + 2) == RPAR && lookahead(offset + 3) == IDENTIFIER) {
1782                PsiBuilder.Marker error = mark();
1783    
1784                advance(offset);
1785    
1786                advance(); // LPAR
1787                if (!word.equals(myBuilder.getTokenText())) {
1788                    // something other than "out" / "Mutable"
1789                    error.rollbackTo();
1790                    return false;
1791                }
1792                else {
1793                    advance(); // IDENTIFIER('out')
1794                    advance(); // RPAR
1795    
1796                    if (consume) {
1797                        error.error("Unexpected tokens");
1798                    }
1799                    else {
1800                        error.rollbackTo();
1801                    }
1802    
1803                    return true;
1804                }
1805            }
1806            return false;
1807        }
1808    
1809        private void recoverOnPlatformTypeSuffix() {
1810            // Recovery for platform types
1811            if (at(EXCL)) {
1812                PsiBuilder.Marker error = mark();
1813                advance(); // EXCL
1814                error.error("Unexpected token");
1815            }
1816        }
1817    
1818        /*
1819         * selfType
1820         *   : "This"
1821         *   ;
1822         */
1823        private void parseSelfType() {
1824            assert _at(CAPITALIZED_THIS_KEYWORD);
1825    
1826            PsiBuilder.Marker type = mark();
1827            advance(); // CAPITALIZED_THIS_KEYWORD
1828            type.done(SELF_TYPE);
1829        }
1830    
1831        /*
1832         *  (optionalProjection type){","}
1833         */
1834        private PsiBuilder.Marker parseTypeArgumentList() {
1835            if (!at(LT)) return null;
1836    
1837            PsiBuilder.Marker list = mark();
1838    
1839            tryParseTypeArgumentList(TokenSet.EMPTY);
1840    
1841            list.done(TYPE_ARGUMENT_LIST);
1842            return list;
1843        }
1844    
1845        boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
1846            myBuilder.disableNewlines();
1847            advance(); // LT
1848    
1849            while (true) {
1850                PsiBuilder.Marker projection = mark();
1851    
1852                recoverOnParenthesizedWordForPlatformTypes(0, "out", true);
1853    
1854    //            TokenSet lookFor = TokenSet.create(IDENTIFIER);
1855    //            TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
1856    //            parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
1857                // Currently we do not allow annotations
1858                parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1859    
1860                if (at(MUL)) {
1861                    advance(); // MUL
1862                }
1863                else {
1864                    parseTypeRef(extraRecoverySet);
1865                }
1866                projection.done(TYPE_PROJECTION);
1867                if (!at(COMMA)) break;
1868                advance(); // COMMA
1869            }
1870    
1871            boolean atGT = at(GT);
1872            if (!atGT) {
1873                error("Expecting a '>'");
1874            }
1875            else {
1876                advance(); // GT
1877            }
1878            myBuilder.restoreNewlinesState();
1879            return atGT;
1880        }
1881    
1882        private void parseModifierListWithShortAnnotations(IElementType modifierList, TokenSet lookFor, TokenSet stopAt) {
1883            int lastId = findLastBefore(lookFor, stopAt, false);
1884            createTruncatedBuilder(lastId).parseModifierList(modifierList, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
1885        }
1886    
1887        /*
1888         * tupleType
1889         *   : "#" "(" type{","}? ")"
1890         *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
1891         *   ;
1892         */
1893        @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1894        private void parseTupleType() {
1895            assert _at(HASH);
1896    
1897            PsiBuilder.Marker tuple = mark();
1898    
1899            myBuilder.disableNewlines();
1900            advance(); // HASH
1901            consumeIf(LPAR);
1902    
1903            if (!at(RPAR)) {
1904                while (true) {
1905                    if (at(COLON)) {
1906                        errorAndAdvance("Expecting a name for tuple entry");
1907                    }
1908    
1909                    if (at(IDENTIFIER) && lookahead(1) == COLON) {
1910                        advance(); // IDENTIFIER
1911                        advance(); // COLON
1912                        parseTypeRef();
1913                    }
1914                    else if (TYPE_REF_FIRST.contains(tt())) {
1915                        parseTypeRef();
1916                    }
1917                    else {
1918                        error("Type expected");
1919                        break;
1920                    }
1921                    if (!at(COMMA)) break;
1922                    advance(); // COMMA
1923                }
1924            }
1925    
1926            consumeIf(RPAR);
1927            myBuilder.restoreNewlinesState();
1928    
1929            tuple.error("Tuples are not supported. Use data classes instead.");
1930        }
1931    
1932        /*
1933         * functionType
1934         *   : "(" (parameter | modifiers type){","}? ")" "->" type?
1935         *   ;
1936         */
1937        private void parseFunctionType() {
1938            parseFunctionTypeContents().done(FUNCTION_TYPE);
1939        }
1940    
1941        private PsiBuilder.Marker parseFunctionTypeContents() {
1942            assert _at(LPAR) : tt();
1943            PsiBuilder.Marker functionType = mark();
1944    
1945            parseValueParameterList(true, /* typeRequired  = */ true, TokenSet.EMPTY);
1946    
1947            expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
1948            parseTypeRef();
1949    
1950            return functionType;
1951        }
1952    
1953        /*
1954         * functionParameters
1955         *   : "(" functionParameter{","}? ")" // default values
1956         *   ;
1957         *
1958         * functionParameter
1959         *   : modifiers functionParameterRest
1960         *   ;
1961         *
1962         * functionParameterRest
1963         *   : parameter ("=" element)?
1964         *   ;
1965         */
1966        void parseValueParameterList(boolean isFunctionTypeContents, boolean typeRequired, TokenSet recoverySet) {
1967            assert _at(LPAR);
1968            PsiBuilder.Marker parameters = mark();
1969    
1970            myBuilder.disableNewlines();
1971            advance(); // LPAR
1972    
1973            if (!at(RPAR) && !atSet(recoverySet)) {
1974                while (true) {
1975                    if (at(COMMA)) {
1976                        errorAndAdvance("Expecting a parameter declaration");
1977                    }
1978                    else if (at(RPAR)) {
1979                        error("Expecting a parameter declaration");
1980                        break;
1981                    }
1982    
1983                    if (isFunctionTypeContents) {
1984                        if (!tryParseValueParameter(typeRequired)) {
1985                            PsiBuilder.Marker valueParameter = mark();
1986                            parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS); // lazy, out, ref
1987                            parseTypeRef();
1988                            closeDeclarationWithCommentBinders(valueParameter, VALUE_PARAMETER, false);
1989                        }
1990                    }
1991                    else {
1992                        parseValueParameter(typeRequired);
1993                    }
1994    
1995                    if (at(COMMA)) {
1996                        advance(); // COMMA
1997                    }
1998                    else {
1999                        if (!at(RPAR)) error("Expecting comma or ')'");
2000                        if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break;
2001                    }
2002                }
2003            }
2004    
2005            expect(RPAR, "Expecting ')'", recoverySet);
2006            myBuilder.restoreNewlinesState();
2007    
2008            parameters.done(VALUE_PARAMETER_LIST);
2009        }
2010    
2011        /*
2012         * functionParameter
2013         *   : modifiers ("val" | "var")? parameter ("=" element)?
2014         *   ;
2015         */
2016        private boolean tryParseValueParameter(boolean typeRequired) {
2017            return parseValueParameter(true, typeRequired);
2018        }
2019    
2020        public void parseValueParameter(boolean typeRequired) {
2021            parseValueParameter(false, typeRequired);
2022        }
2023    
2024        private boolean parseValueParameter(boolean rollbackOnFailure, boolean typeRequired) {
2025            PsiBuilder.Marker parameter = mark();
2026    
2027            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON));
2028    
2029            if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
2030                advance(); // VAR_KEYWORD | VAL_KEYWORD
2031            }
2032    
2033            if (!parseFunctionParameterRest(typeRequired) && rollbackOnFailure) {
2034                parameter.rollbackTo();
2035                return false;
2036            }
2037    
2038            closeDeclarationWithCommentBinders(parameter, VALUE_PARAMETER, false);
2039            return true;
2040        }
2041    
2042        /*
2043         * functionParameterRest
2044         *   : parameter ("=" element)?
2045         *   ;
2046         */
2047        private boolean parseFunctionParameterRest(boolean typeRequired) {
2048            boolean noErrors = true;
2049    
2050            // Recovery for the case 'fun foo(Array<String>) {}'
2051            if (at(IDENTIFIER) && lookahead(1) == LT) {
2052                error("Parameter name expected");
2053                parseTypeRef();
2054                noErrors = false;
2055            }
2056            else {
2057                expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
2058    
2059                if (at(COLON)) {
2060                    advance(); // COLON
2061                    parseTypeRef();
2062                }
2063                else if (typeRequired) {
2064                    errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
2065                    noErrors = false;
2066                }
2067            }
2068    
2069            if (at(EQ)) {
2070                advance(); // EQ
2071                myExpressionParsing.parseExpression();
2072            }
2073    
2074            return noErrors;
2075        }
2076    
2077        @Override
2078        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
2079            return createForTopLevel(builder);
2080        }
2081    
2082        /*package*/ static class ModifierDetector implements Consumer<IElementType> {
2083            private boolean enumDetected = false;
2084            private boolean defaultDetected = false;
2085    
2086            @Override
2087            public void consume(IElementType item) {
2088                if (item == JetTokens.ENUM_KEYWORD) {
2089                    enumDetected = true;
2090                }
2091                else if (item == JetTokens.COMPANION_KEYWORD) {
2092                    defaultDetected = true;
2093                }
2094            }
2095    
2096            public boolean isEnumDetected() {
2097                return enumDetected;
2098            }
2099    
2100            public boolean isDefaultDetected() {
2101                return defaultDetected;
2102            }
2103        }
2104    
2105        static enum AnnotationParsingMode {
2106            FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true),
2107            FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true),
2108            REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS(false, false),
2109            REGULAR_ANNOTATIONS_ALLOW_SHORTS(true, false),
2110            REGULAR_ANNOTATIONS_ALLOW_SHORTS_AT_MEMBER_MODIFIER_LIST(true, false, true);
2111    
2112            boolean allowShortAnnotations;
2113            boolean isFileAnnotationParsingMode;
2114            boolean atMemberStart = false;
2115    
2116            AnnotationParsingMode(boolean allowShortAnnotations, boolean onlyFileAnnotations) {
2117                this.allowShortAnnotations = allowShortAnnotations;
2118                this.isFileAnnotationParsingMode = onlyFileAnnotations;
2119            }
2120    
2121            AnnotationParsingMode(boolean allowShortAnnotations, boolean onlyFileAnnotations, boolean atMemberStart) {
2122                this(allowShortAnnotations, onlyFileAnnotations);
2123                this.atMemberStart = atMemberStart;
2124            }
2125        }
2126    }