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