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_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD,
047                    FUN_KEYWORD, VAL_KEYWORD, PACKAGE_KEYWORD);
048        private static final TokenSet ENUM_MEMBER_FIRST = TokenSet.create(TYPE_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_KEYWORD) {
371                declType = parseTypeDef();
372            }
373            else if (keywordToken == OBJECT_KEYWORD) {
374                parseObject(true, true);
375                declType = OBJECT_DECLARATION;
376            }
377    
378            if (declType == null) {
379                errorAndAdvance("Expecting package directive or 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        IElementType parseClass(boolean enumClass) {
560            assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD);
561            advance(); // CLASS_KEYWORD or TRAIT_KEYWORD
562    
563            expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
564            boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
565    
566            PsiBuilder.Marker beforeConstructorModifiers = mark();
567            boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
568    
569            // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
570            if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON) ) {
571                beforeConstructorModifiers.rollbackTo();
572                return CLASS;
573            }
574    
575            // We are still inside a class declaration
576            beforeConstructorModifiers.drop();
577    
578            if (at(LPAR)) {
579                parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
580            }
581            else if (hasConstructorModifiers) {
582                // A comprehensive error message for cases like:
583                //    class A private : Foo
584                // or
585                //    class A private {
586                error("Expecting primary constructor parameter list");
587            }
588    
589            if (at(COLON)) {
590                advance(); // COLON
591                parseDelegationSpecifierList();
592            }
593    
594            parseTypeConstraintsGuarded(typeParametersDeclared);
595    
596            if (at(LBRACE)) {
597                if (enumClass) {
598                    parseEnumClassBody();
599                }
600                else {
601                    parseClassBody();
602                }
603            }
604    
605            return CLASS;
606        }
607    
608        /*
609         * enumClassBody
610         *   : "{" (enumEntry | memberDeclaration)* "}"
611         *   ;
612         */
613        private void parseEnumClassBody() {
614            if (!at(LBRACE)) return;
615    
616            PsiBuilder.Marker classBody = mark();
617    
618            myBuilder.enableNewlines();
619            advance(); // LBRACE
620    
621            while (!eof() && !at(RBRACE)) {
622                PsiBuilder.Marker entryOrMember = mark();
623    
624                TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
625                int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
626                TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
627                createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
628    
629                IElementType type;
630                if (at(IDENTIFIER)) {
631                    parseEnumEntry();
632                    type = ENUM_ENTRY;
633                }
634                else {
635                    type = parseMemberDeclarationRest(enumDetector.isDetected());
636                }
637    
638                if (type == null) {
639                    errorAndAdvance("Expecting an enum entry or member declaration");
640                    entryOrMember.drop();
641                }
642                else {
643                    entryOrMember.done(type);
644                }
645            }
646    
647            expect(RBRACE, "Expecting '}' to close enum class body");
648            myBuilder.restoreNewlinesState();
649    
650            classBody.done(CLASS_BODY);
651        }
652    
653        /*
654         * enumEntry
655         *   : modifiers SimpleName (":" initializer{","})? classBody?
656         *   ;
657         */
658        private void parseEnumEntry() {
659            assert _at(IDENTIFIER);
660    
661            PsiBuilder.Marker nameAsDeclaration = mark();
662            advance(); // IDENTIFIER
663            nameAsDeclaration.done(OBJECT_DECLARATION_NAME);
664    
665            if (at(COLON)) {
666                advance(); // COLON
667    
668                parseInitializerList();
669            }
670    
671            if (at(LBRACE)) {
672                parseClassBody();
673            }
674    
675            consumeIf(SEMICOLON);
676        }
677    
678        /*
679         * classBody
680         *   : ("{" memberDeclaration* "}")?
681         *   ;
682         */
683        private void parseClassBody() {
684            PsiBuilder.Marker body = mark();
685    
686            myBuilder.enableNewlines();
687    
688            if (expect(LBRACE, "Expecting a class body")) {
689                while (!eof()) {
690                    if (at(RBRACE)) {
691                        break;
692                    }
693                    parseMemberDeclaration();
694                }
695                expect(RBRACE, "Missing '}");
696            }
697    
698            myBuilder.restoreNewlinesState();
699    
700            body.done(CLASS_BODY);
701        }
702    
703        /*
704         * memberDeclaration
705         *   : modifiers memberDeclaration'
706         *   ;
707         *
708         * memberDeclaration'
709         *   : classObject
710         *   : constructor
711         *   : function
712         *   : property
713         *   : class
714         *   : extension
715         *   : typedef
716         *   : anonymousInitializer
717         *   : object
718         *   ;
719         */
720        private void parseMemberDeclaration() {
721            PsiBuilder.Marker decl = mark();
722    
723            TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
724            parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
725    
726            IElementType declType = parseMemberDeclarationRest(enumDetector.isDetected());
727    
728            if (declType == null) {
729                errorWithRecovery("Expecting member declaration", TokenSet.create(RBRACE));
730                decl.drop();
731            }
732            else {
733                decl.done(declType);
734            }
735        }
736    
737        private IElementType parseMemberDeclarationRest(boolean isEnum) {
738            IElementType keywordToken = tt();
739            IElementType declType = null;
740            if (keywordToken == CLASS_KEYWORD) {
741                if (lookahead(1) == OBJECT_KEYWORD) {
742                    declType = parseClassObject();
743                }
744                else {
745                    declType = parseClass(isEnum);
746                }
747            }
748            else if (keywordToken == TRAIT_KEYWORD) {
749                declType = parseClass(isEnum);
750            }
751            else if (keywordToken == FUN_KEYWORD) {
752                    declType = parseFunction();
753            }
754            else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
755                declType = parseProperty();
756            }
757            else if (keywordToken == TYPE_KEYWORD) {
758                declType = parseTypeDef();
759            }
760            else if (keywordToken == OBJECT_KEYWORD) {
761                parseObject(true, true);
762                declType = OBJECT_DECLARATION;
763            }
764            else if (keywordToken == LBRACE) {
765                parseBlock();
766                declType = ANONYMOUS_INITIALIZER;
767            }
768            return declType;
769        }
770    
771        /*
772         * object
773         *   : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
774         *   ;
775         */
776        void parseObject(boolean named, boolean optionalBody) {
777            assert _at(OBJECT_KEYWORD);
778    
779            advance(); // OBJECT_KEYWORD
780    
781            if (named) {
782                PsiBuilder.Marker propertyDeclaration = mark();
783                expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
784                propertyDeclaration.done(OBJECT_DECLARATION_NAME);
785            }
786            else {
787                if (at(IDENTIFIER)) {
788                    error("An object expression cannot bind a name");
789                }
790            }
791    
792            if (optionalBody) {
793                if (at(COLON)) {
794                    advance(); // COLON
795                    parseDelegationSpecifierList();
796                }
797                if (at(LBRACE)) {
798                    parseClassBody();
799                }
800            }
801            else {
802                if (at(LBRACE)) {
803                    parseClassBody();
804                }
805                else {
806                    expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, PACKAGE_KEYWORD));
807                    parseDelegationSpecifierList();
808                    parseClassBody();
809                }
810            }
811        }
812    
813        /*
814         * initializer{","}
815         */
816        private void parseInitializerList() {
817            PsiBuilder.Marker list = mark();
818            while (true) {
819                if (at(COMMA)) errorAndAdvance("Expecting a this or super constructor call");
820                parseInitializer();
821                if (!at(COMMA)) break;
822                advance(); // COMMA
823            }
824            list.done(INITIALIZER_LIST);
825        }
826    
827        /*
828         * initializer
829         *   : annotations "this" valueArguments
830         *   : annotations constructorInvocation // type parameters may (must?) be omitted
831         *   ;
832         */
833        private void parseInitializer() {
834            PsiBuilder.Marker initializer = mark();
835            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
836    
837            IElementType type;
838            if (at(THIS_KEYWORD)) {
839                PsiBuilder.Marker mark = mark();
840                advance(); // THIS_KEYWORD
841                mark.done(THIS_CONSTRUCTOR_REFERENCE);
842                type = THIS_CALL;
843            }
844            else if (atSet(TYPE_REF_FIRST)) {
845                PsiBuilder.Marker reference = mark();
846                parseTypeRef();
847                reference.done(CONSTRUCTOR_CALLEE);
848                type = DELEGATOR_SUPER_CALL;
849            }
850            else {
851                errorWithRecovery("Expecting constructor call (this(...)) or supertype initializer",
852                                  TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(RBRACE, LBRACE, COMMA, SEMICOLON)));
853                initializer.drop();
854                return;
855            }
856            myExpressionParsing.parseValueArgumentList();
857    
858            initializer.done(type);
859        }
860    
861        /*
862         * classObject
863         *   : modifiers "class" object
864         *   ;
865         */
866        private IElementType parseClassObject() {
867            assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD;
868    
869            advance(); // CLASS_KEYWORD
870    
871            PsiBuilder.Marker objectDeclaration = mark();
872            parseObject(false, true);
873            objectDeclaration.done(OBJECT_DECLARATION);
874    
875            return CLASS_OBJECT;
876        }
877    
878        /*
879         * typedef
880         *   : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
881         *   ;
882         */
883        JetNodeType parseTypeDef() {
884            assert _at(TYPE_KEYWORD);
885    
886            advance(); // TYPE_KEYWORD
887    
888            expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
889    
890            if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
891                parseTypeConstraints();
892            }
893    
894            expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
895    
896            parseTypeRef();
897    
898            consumeIf(SEMICOLON);
899    
900            return TYPEDEF;
901        }
902    
903        /*
904         * variableDeclarationEntry
905         *   : SimpleName (":" type)?
906         *   ;
907         *
908         * property
909         *   : modifiers ("val" | "var")
910         *       typeParameters? (type "." | annotations)?
911         *       ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
912         *       typeConstraints
913         *       ("by" | "=" expression SEMI?)?
914         *       (getter? setter? | setter? getter?) SEMI?
915         *   ;
916         */
917        private IElementType parseProperty() {
918            return parseProperty(false);
919        }
920    
921        public IElementType parseProperty(boolean local) {
922            if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
923                advance(); // VAL_KEYWORD or VAR_KEYWORD
924            }
925            else {
926                errorAndAdvance("Expecting 'val' or 'var'");
927            }
928    
929            boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
930    
931            TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
932    
933            myBuilder.disableJoiningComplexTokens();
934    
935            // TODO: extract constant
936            int lastDot = matchTokenStreamPredicate(new LastBefore(
937                    new AtSet(DOT, SAFE_ACCESS),
938                    new AbstractTokenStreamPredicate() {
939                        @Override
940                        public boolean matching(boolean topLevel) {
941                            if (topLevel && (at(EQ) || at(COLON))) return true;
942                            if (topLevel && at(IDENTIFIER)) {
943                                IElementType lookahead = lookahead(1);
944                                return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
945                            }
946                            return false;
947                        }
948                    }));
949    
950            PsiBuilder.Marker receiver = mark();
951            parseReceiverType("property", propertyNameFollow, lastDot);
952    
953            boolean multiDeclaration = at(LPAR);
954            boolean receiverTypeDeclared = lastDot != -1;
955    
956            errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
957    
958            if (multiDeclaration) {
959                PsiBuilder.Marker multiDecl = mark();
960                parseMultiDeclarationName(propertyNameFollow);
961                errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
962            }
963            else {
964                parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow);
965            }
966    
967            myBuilder.restoreJoiningComplexTokensState();
968    
969            if (at(COLON)) {
970                PsiBuilder.Marker type = mark();
971                advance(); // COLON
972                parseTypeRef();
973                errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
974            }
975    
976            parseTypeConstraintsGuarded(typeParametersDeclared);
977    
978            if (local) {
979                if (at(BY_KEYWORD)) {
980                    parsePropertyDelegate();
981                }
982                else if (at(EQ)) {
983                    advance(); // EQ
984                    myExpressionParsing.parseExpression();
985                    // "val a = 1; b" must not be an infix call of b on "val ...;"
986                }
987            }
988            else {
989                if (at(BY_KEYWORD)) {
990                    parsePropertyDelegate();
991                    consumeIf(SEMICOLON);
992                }
993                else if (at(EQ)) {
994                    advance(); // EQ
995                    myExpressionParsing.parseExpression();
996                    consumeIf(SEMICOLON);
997                }
998    
999                if (parsePropertyGetterOrSetter()) {
1000                    parsePropertyGetterOrSetter();
1001                }
1002                if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
1003                    if (getLastToken() != SEMICOLON) {
1004                        errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON));
1005                    }
1006                }
1007                else {
1008                    consumeIf(SEMICOLON);
1009                }
1010            }
1011    
1012            return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
1013        }
1014    
1015        /*
1016         * propertyDelegate
1017         *   : "by" expression
1018         *   ;
1019         */
1020        private void parsePropertyDelegate() {
1021            assert _at(BY_KEYWORD);
1022            PsiBuilder.Marker delegate = mark();
1023            advance(); // BY_KEYWORD
1024            myExpressionParsing.parseExpression();
1025            delegate.done(PROPERTY_DELEGATE);
1026        }
1027    
1028        /*
1029         * (SimpleName (":" type)){","}
1030         */
1031        public void parseMultiDeclarationName(TokenSet follow) {
1032            // Parsing multi-name, e.g.
1033            //   val (a, b) = foo()
1034            myBuilder.disableNewlines();
1035            advance(); // LPAR
1036    
1037            TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
1038            if (!atSet(follow)) {
1039                while (true) {
1040                    if (at(COMMA)) {
1041                        errorAndAdvance("Expecting a name");
1042                    }
1043                    else if (at(RPAR)) {
1044                        error("Expecting a name");
1045                        break;
1046                    }
1047                    PsiBuilder.Marker property = mark();
1048                    expect(IDENTIFIER, "Expecting a name", recoverySet);
1049    
1050                    if (at(COLON)) {
1051                        advance(); // COLON
1052                        parseTypeRef(follow);
1053                    }
1054                    property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
1055    
1056                    if (!at(COMMA)) break;
1057                    advance(); // COMMA
1058                }
1059            }
1060    
1061            expect(RPAR, "Expecting ')'", follow);
1062            myBuilder.restoreNewlinesState();
1063        }
1064    
1065        /*
1066         * getterOrSetter
1067         *   : modifiers ("get" | "set")
1068         *   :
1069         *        (     "get" "(" ")"
1070         *           |
1071         *              "set" "(" modifiers parameter ")"
1072         *        ) functionBody
1073         *   ;
1074         */
1075        private boolean parsePropertyGetterOrSetter() {
1076            PsiBuilder.Marker getterOrSetter = mark();
1077    
1078            parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1079    
1080            if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
1081                getterOrSetter.rollbackTo();
1082                return false;
1083            }
1084    
1085            boolean setter = at(SET_KEYWORD);
1086            advance(); // GET_KEYWORD or SET_KEYWORD
1087    
1088            if (!at(LPAR)) {
1089                // Account for Jet-114 (val a : int get {...})
1090                TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1091                if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1092                    errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1093                }
1094                else {
1095                    getterOrSetter.done(PROPERTY_ACCESSOR);
1096                    return true;
1097                }
1098            }
1099    
1100            myBuilder.disableNewlines();
1101            expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1102            if (setter) {
1103                PsiBuilder.Marker parameterList = mark();
1104                PsiBuilder.Marker setterParameter = mark();
1105                parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON));
1106                expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1107    
1108                if (at(COLON)) {
1109                    advance();  // COLON
1110                    parseTypeRef();
1111                }
1112                setterParameter.done(VALUE_PARAMETER);
1113                parameterList.done(VALUE_PARAMETER_LIST);
1114            }
1115            if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON));
1116            expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1117            myBuilder.restoreNewlinesState();
1118    
1119            if (at(COLON)) {
1120                advance();
1121    
1122                parseTypeRef();
1123            }
1124    
1125            parseFunctionBody();
1126    
1127            getterOrSetter.done(PROPERTY_ACCESSOR);
1128    
1129            return true;
1130        }
1131    
1132        /*
1133         * function
1134         *   : modifiers "fun" typeParameters?
1135         *       (type "." | annotations)?
1136         *       SimpleName
1137         *       typeParameters? functionParameters (":" type)?
1138         *       typeConstraints
1139         *       functionBody?
1140         *   ;
1141         */
1142        IElementType parseFunction() {
1143            assert _at(FUN_KEYWORD);
1144    
1145            advance(); // FUN_KEYWORD
1146    
1147            // Recovery for the case of class A { fun| }
1148            if (at(RBRACE)) {
1149                error("Function body expected");
1150                return FUN;
1151            }
1152    
1153            boolean typeParameterListOccurred = false;
1154            if (at(LT)) {
1155                parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
1156                typeParameterListOccurred = true;
1157            }
1158    
1159            myBuilder.disableJoiningComplexTokens();
1160            int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true);
1161    
1162            TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
1163            parseReceiverType("function", functionNameFollow, lastDot);
1164    
1165            parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow);
1166    
1167            myBuilder.restoreJoiningComplexTokensState();
1168    
1169            TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
1170    
1171            if (at(LT)) {
1172                PsiBuilder.Marker error = mark();
1173                parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1174                errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1175                typeParameterListOccurred = true;
1176            }
1177    
1178            if (at(LPAR)) {
1179                parseValueParameterList(false, valueParametersFollow);
1180            }
1181            else {
1182                error("Expecting '('");
1183            }
1184    
1185            if (at(COLON)) {
1186                advance(); // COLON
1187    
1188                parseTypeRef();
1189            }
1190    
1191            parseTypeConstraintsGuarded(typeParameterListOccurred);
1192    
1193            if (at(SEMICOLON)) {
1194                advance(); // SEMICOLON
1195            }
1196            else if (at(EQ) || at(LBRACE)) {
1197                parseFunctionBody();
1198            }
1199    
1200            return FUN;
1201        }
1202    
1203        /*
1204         *   (type "." | annotations)?
1205         */
1206        private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) {
1207            if (lastDot == -1) { // There's no explicit receiver type specified
1208                parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1209            }
1210            else {
1211                createTruncatedBuilder(lastDot).parseTypeRef();
1212    
1213                if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1214                    advance(); // expectation
1215                }
1216                else {
1217                    errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1218                }
1219            }
1220        }
1221    
1222        /*
1223         * IDENTIFIER
1224         */
1225        private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow) {
1226            if (!receiverFound) {
1227                expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow);
1228            }
1229            else {
1230                expect(IDENTIFIER, "Expecting " + title + " name", nameFollow);
1231            }
1232        }
1233    
1234        /*
1235         * functionBody
1236         *   : block
1237         *   : "=" element
1238         *   ;
1239         */
1240        private void parseFunctionBody() {
1241            if (at(LBRACE)) {
1242                parseBlock();
1243            }
1244            else if (at(EQ)) {
1245                advance(); // EQ
1246                myExpressionParsing.parseExpression();
1247                consumeIf(SEMICOLON);
1248            }
1249            else {
1250                errorAndAdvance("Expecting function body");
1251            }
1252        }
1253    
1254        /*
1255         * block
1256         *   : "{" (expressions)* "}"
1257         *   ;
1258         */
1259        void parseBlock() {
1260            PsiBuilder.Marker block = mark();
1261    
1262            myBuilder.enableNewlines();
1263            expect(LBRACE, "Expecting '{' to open a block");
1264    
1265            myExpressionParsing.parseStatements();
1266    
1267            expect(RBRACE, "Expecting '}");
1268            myBuilder.restoreNewlinesState();
1269    
1270            block.done(BLOCK);
1271        }
1272    
1273        /*
1274         * delegationSpecifier{","}
1275         */
1276        /*package*/ void parseDelegationSpecifierList() {
1277            PsiBuilder.Marker list = mark();
1278    
1279            while (true) {
1280                if (at(COMMA)) {
1281                    errorAndAdvance("Expecting a delegation specifier");
1282                    continue;
1283                }
1284                parseDelegationSpecifier();
1285                if (!at(COMMA)) break;
1286                advance(); // COMMA
1287            }
1288    
1289            list.done(DELEGATION_SPECIFIER_LIST);
1290        }
1291    
1292        /*
1293         * annotations delegationSpecifier
1294         *
1295         * delegationSpecifier
1296         *   : constructorInvocation // type and constructor arguments
1297         *   : userType
1298         *   : explicitDelegation
1299         *   ;
1300         *
1301         * explicitDelegation
1302         *   : userType "by" element
1303         *   ;
1304         */
1305        private void parseDelegationSpecifier() {
1306            PsiBuilder.Marker delegator = mark();
1307            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1308    
1309            PsiBuilder.Marker reference = mark();
1310            parseTypeRef();
1311    
1312            if (at(BY_KEYWORD)) {
1313                reference.drop();
1314                advance(); // BY_KEYWORD
1315                createForByClause(myBuilder).myExpressionParsing.parseExpression();
1316                delegator.done(DELEGATOR_BY);
1317            }
1318            else if (at(LPAR)) {
1319                reference.done(CONSTRUCTOR_CALLEE);
1320                myExpressionParsing.parseValueArgumentList();
1321                delegator.done(DELEGATOR_SUPER_CALL);
1322            }
1323            else {
1324                reference.drop();
1325                delegator.done(DELEGATOR_SUPER_CLASS);
1326            }
1327        }
1328    
1329        /*
1330         * typeParameters
1331         *   : ("<" typeParameter{","} ">"
1332         *   ;
1333         */
1334        private boolean parseTypeParameterList(TokenSet recoverySet) {
1335            boolean result = false;
1336            if (at(LT)) {
1337                PsiBuilder.Marker list = mark();
1338    
1339                myBuilder.disableNewlines();
1340                advance(); // LT
1341    
1342                while (true) {
1343                    if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1344                    parseTypeParameter();
1345    
1346                    if (!at(COMMA)) break;
1347                    advance(); // COMMA
1348                }
1349    
1350                expect(GT, "Missing '>'", recoverySet);
1351                myBuilder.restoreNewlinesState();
1352                result = true;
1353    
1354                list.done(TYPE_PARAMETER_LIST);
1355            }
1356            return result;
1357        }
1358    
1359        /*
1360         * typeConstraints
1361         *   : ("where" typeConstraint{","})?
1362         *   ;
1363         */
1364        private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1365            PsiBuilder.Marker error = mark();
1366            boolean constraints = parseTypeConstraints();
1367            errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1368        }
1369    
1370        private boolean parseTypeConstraints() {
1371            if (at(WHERE_KEYWORD)) {
1372                parseTypeConstraintList();
1373                return true;
1374            }
1375            return false;
1376        }
1377    
1378        /*
1379         * typeConstraint{","}
1380         */
1381        private void parseTypeConstraintList() {
1382            assert _at(WHERE_KEYWORD);
1383    
1384            advance(); // WHERE_KEYWORD
1385    
1386            PsiBuilder.Marker list = mark();
1387    
1388            while (true) {
1389                if (at(COMMA)) errorAndAdvance("Type constraint expected");
1390                parseTypeConstraint();
1391                if (!at(COMMA)) break;
1392                advance(); // COMMA
1393            }
1394    
1395            list.done(TYPE_CONSTRAINT_LIST);
1396        }
1397    
1398        /*
1399         * typeConstraint
1400         *   : annotations SimpleName ":" type
1401         *   : annotations "class" "object" SimpleName ":" type
1402         *   ;
1403         */
1404        private void parseTypeConstraint() {
1405            PsiBuilder.Marker constraint = mark();
1406    
1407            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1408    
1409            if (at(CLASS_KEYWORD)) {
1410                advance(); // CLASS_KEYWORD
1411    
1412                expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST);
1413    
1414            }
1415    
1416            PsiBuilder.Marker reference = mark();
1417            if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) {
1418                reference.done(REFERENCE_EXPRESSION);
1419            }
1420            else {
1421                reference.drop();
1422            }
1423    
1424            expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
1425    
1426            parseTypeRef();
1427    
1428            constraint.done(TYPE_CONSTRAINT);
1429        }
1430    
1431        /*
1432         * typeParameter
1433         *   : modifiers SimpleName (":" userType)?
1434         *   ;
1435         */
1436        private void parseTypeParameter() {
1437            if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1438                error("Type parameter declaration expected");
1439                return;
1440            }
1441    
1442            PsiBuilder.Marker mark = mark();
1443    
1444            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON));
1445    
1446            expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1447    
1448            if (at(COLON)) {
1449                advance(); // COLON
1450                parseTypeRef();
1451            }
1452    
1453            mark.done(TYPE_PARAMETER);
1454    
1455        }
1456    
1457        /*
1458         * type
1459         *   : annotations typeDescriptor
1460         *
1461         * typeDescriptor
1462         *   : selfType
1463         *   : functionType
1464         *   : userType
1465         *   : tupleType
1466         *   : nullableType
1467         *   ;
1468         *
1469         * nullableType
1470         *   : typeDescriptor "?"
1471         */
1472        void parseTypeRef() {
1473            parseTypeRef(TokenSet.EMPTY);
1474        }
1475    
1476        void parseTypeRef(TokenSet extraRecoverySet) {
1477            PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1478            typeRefMarker.done(TYPE_REFERENCE);
1479        }
1480    
1481        // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1482        // on expression-indicating symbols or not
1483        private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1484            // Disabling token merge is required for cases like
1485            //    Int?.(Foo) -> Bar
1486            // we don't support this case now
1487    //        myBuilder.disableJoiningComplexTokens();
1488            PsiBuilder.Marker typeRefMarker = mark();
1489            parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1490    
1491            if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
1492                parseUserType();
1493            }
1494            else if (at(HASH)) {
1495                parseTupleType();
1496            }
1497            else if (at(LPAR)) {
1498                PsiBuilder.Marker functionOrParenthesizedType = mark();
1499    
1500                // This may be a function parameter list or just a prenthesized type
1501                advance(); // LPAR
1502                parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1503    
1504                if (at(RPAR)) {
1505                    advance(); // RPAR
1506                    if (at(ARROW)) {
1507                        // It's a function type with one parameter specified
1508                        //    (A) -> B
1509                        functionOrParenthesizedType.rollbackTo();
1510                        parseFunctionType();
1511                    }
1512                    else {
1513                        // It's a parenthesized type
1514                        //    (A)
1515                        functionOrParenthesizedType.drop();
1516                    }
1517                }
1518                else {
1519                    // This must be a function type
1520                    //   (A, B) -> C
1521                    // or
1522                    //   (a : A) -> C
1523                    functionOrParenthesizedType.rollbackTo();
1524                    parseFunctionType();
1525                }
1526    
1527            }
1528            else if (at(CAPITALIZED_THIS_KEYWORD)) {
1529                parseSelfType();
1530            }
1531            else {
1532                errorWithRecovery("Type expected",
1533                        TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
1534                                       TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
1535            }
1536    
1537            typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
1538    
1539            if (at(DOT)) {
1540                // This is a receiver for a function type
1541                //  A.(B) -> C
1542                //   ^
1543    
1544                PsiBuilder.Marker functionType = typeRefMarker.precede();
1545                PsiBuilder.Marker receiverType = typeRefMarker.precede();
1546                typeRefMarker.done(TYPE_REFERENCE);
1547                receiverType.done(FUNCTION_TYPE_RECEIVER);
1548    
1549                advance(); // DOT
1550    
1551                if (at(LPAR)) {
1552                    parseFunctionTypeContents().drop();
1553                }
1554                else {
1555                    error("Expecting function type");
1556                }
1557                typeRefMarker = functionType.precede();
1558    
1559                functionType.done(FUNCTION_TYPE);
1560            }
1561    //        myBuilder.restoreJoiningComplexTokensState();
1562            return typeRefMarker;
1563        }
1564    
1565        @NotNull
1566        PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
1567            while (at(QUEST)) {
1568                PsiBuilder.Marker precede = typeRefMarker.precede();
1569                advance(); // QUEST
1570                typeRefMarker.done(NULLABLE_TYPE);
1571                typeRefMarker = precede;
1572            }
1573            return typeRefMarker;
1574        }
1575    
1576        /*
1577         * userType
1578         *   : ("package" ".")? simpleUserType{"."}
1579         *   ;
1580         */
1581        void parseUserType() {
1582            PsiBuilder.Marker userType = mark();
1583    
1584            if (at(PACKAGE_KEYWORD)) {
1585                advance(); // PACKAGE_KEYWORD
1586                expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER));
1587            }
1588    
1589            PsiBuilder.Marker reference = mark();
1590            while (true) {
1591                if (expect(IDENTIFIER, "Expecting type name",
1592                           TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
1593                    reference.done(REFERENCE_EXPRESSION);
1594                }
1595                else {
1596                    reference.drop();
1597                    break;
1598                }
1599    
1600                parseTypeArgumentList();
1601                if (!at(DOT)) {
1602                    break;
1603                }
1604                if (lookahead(1) == LPAR) {
1605                    // This may be a receiver for a function type
1606                    //   Int.(Int) -> Int
1607                    break;
1608                }
1609    
1610                PsiBuilder.Marker precede = userType.precede();
1611                userType.done(USER_TYPE);
1612                userType = precede;
1613    
1614                advance(); // DOT
1615                reference = mark();
1616            }
1617    
1618            userType.done(USER_TYPE);
1619        }
1620    
1621        /*
1622         * selfType
1623         *   : "This"
1624         *   ;
1625         */
1626        private void parseSelfType() {
1627            assert _at(CAPITALIZED_THIS_KEYWORD);
1628    
1629            PsiBuilder.Marker type = mark();
1630            advance(); // CAPITALIZED_THIS_KEYWORD
1631            type.done(SELF_TYPE);
1632        }
1633    
1634        /*
1635         *  (optionalProjection type){","}
1636         */
1637        private PsiBuilder.Marker parseTypeArgumentList() {
1638            if (!at(LT)) return null;
1639    
1640            PsiBuilder.Marker list = mark();
1641    
1642            tryParseTypeArgumentList(TokenSet.EMPTY);
1643    
1644            list.done(TYPE_ARGUMENT_LIST);
1645            return list;
1646        }
1647    
1648        boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
1649            myBuilder.disableNewlines();
1650            advance(); // LT
1651    
1652            while (true) {
1653                PsiBuilder.Marker projection = mark();
1654    
1655    //            TokenSet lookFor = TokenSet.create(IDENTIFIER);
1656    //            TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
1657    //            parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
1658                // Currently we do not allow annotations
1659                parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
1660    
1661                if (at(MUL)) {
1662                    advance(); // MUL
1663                }
1664                else {
1665                    parseTypeRef(extraRecoverySet);
1666                }
1667                projection.done(TYPE_PROJECTION);
1668                if (!at(COMMA)) break;
1669                advance(); // COMMA
1670            }
1671    
1672            boolean atGT = at(GT);
1673            if (!atGT) {
1674                error("Expecting a '>'");
1675            }
1676            else {
1677                advance(); // GT
1678            }
1679            myBuilder.restoreNewlinesState();
1680            return atGT;
1681        }
1682    
1683        private void parseModifierListWithShortAnnotations(IElementType modifierList, TokenSet lookFor, TokenSet stopAt) {
1684            int lastId = findLastBefore(lookFor, stopAt, false);
1685            createTruncatedBuilder(lastId).parseModifierList(modifierList, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
1686        }
1687    
1688        /*
1689         * tupleType
1690         *   : "#" "(" type{","}? ")"
1691         *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
1692         *   ;
1693         */
1694        @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1695        private void parseTupleType() {
1696            assert _at(HASH);
1697    
1698            PsiBuilder.Marker tuple = mark();
1699    
1700            myBuilder.disableNewlines();
1701            advance(); // HASH
1702            consumeIf(LPAR);
1703    
1704            if (!at(RPAR)) {
1705                while (true) {
1706                    if (at(COLON)) {
1707                        errorAndAdvance("Expecting a name for tuple entry");
1708                    }
1709    
1710                    if (at(IDENTIFIER) && lookahead(1) == COLON) {
1711                        advance(); // IDENTIFIER
1712                        advance(); // COLON
1713                        parseTypeRef();
1714                    }
1715                    else if (TYPE_REF_FIRST.contains(tt())) {
1716                        parseTypeRef();
1717                    }
1718                    else {
1719                        error("Type expected");
1720                        break;
1721                    }
1722                    if (!at(COMMA)) break;
1723                    advance(); // COMMA
1724                }
1725            }
1726    
1727            consumeIf(RPAR);
1728            myBuilder.restoreNewlinesState();
1729    
1730            tuple.error("Tuples are not supported. Use data classes instead.");
1731        }
1732    
1733        /*
1734         * functionType
1735         *   : "(" (parameter | modifiers type){","}? ")" "->" type?
1736         *   ;
1737         */
1738        private void parseFunctionType() {
1739            parseFunctionTypeContents().done(FUNCTION_TYPE);
1740        }
1741    
1742        private PsiBuilder.Marker parseFunctionTypeContents() {
1743            assert _at(LPAR) : tt();
1744            PsiBuilder.Marker functionType = mark();
1745    
1746    //        advance(); // LPAR
1747    //
1748    //        int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false);
1749    //        if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
1750    //            TODO : -1 is a hack?
1751    //            createTruncatedBuilder(lastLPar - 1).parseTypeRef();
1752    //            advance(); // DOT
1753    //        }
1754    
1755            parseValueParameterList(true, TokenSet.EMPTY);
1756    
1757    //        if (at(COLON)) {
1758    //            advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
1759    
1760            expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
1761            parseTypeRef();
1762    //        }
1763    
1764            return functionType;//.done(FUNCTION_TYPE);
1765        }
1766    
1767        /*
1768         * functionParameters
1769         *   : "(" functionParameter{","}? ")" // default values
1770         *   ;
1771         *
1772         * functionParameter
1773         *   : modifiers functionParameterRest
1774         *   ;
1775         *
1776         * functionParameterRest
1777         *   : parameter ("=" element)?
1778         *   ;
1779         */
1780        void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
1781            assert _at(LPAR);
1782            PsiBuilder.Marker parameters = mark();
1783    
1784            myBuilder.disableNewlines();
1785            advance(); // LPAR
1786    
1787            if (!at(RPAR) && !atSet(recoverySet)) {
1788                while (true) {
1789                    if (at(COMMA)) {
1790                        errorAndAdvance("Expecting a parameter declaration");
1791                    }
1792                    else if (at(RPAR)) {
1793                        error("Expecting a parameter declaration");
1794                        break;
1795                    }
1796    
1797                    if (isFunctionTypeContents) {
1798                        if (!tryParseValueParameter()) {
1799                            PsiBuilder.Marker valueParameter = mark();
1800                            parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS); // lazy, out, ref
1801                            parseTypeRef();
1802                            valueParameter.done(VALUE_PARAMETER);
1803                        }
1804                    }
1805                    else {
1806                        parseValueParameter();
1807                    }
1808    
1809                    if (at(COMMA)) {
1810                        advance(); // COMMA
1811                    }
1812                    else {
1813                        if (!at(RPAR)) error("Expecting comma or ')'");
1814                        if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break;
1815                    }
1816                }
1817            }
1818    
1819            expect(RPAR, "Expecting ')'", recoverySet);
1820            myBuilder.restoreNewlinesState();
1821    
1822            parameters.done(VALUE_PARAMETER_LIST);
1823        }
1824    
1825        /*
1826         * functionParameter
1827         *   : modifiers ("val" | "var")? parameter ("=" element)?
1828         *   ;
1829         */
1830        private boolean tryParseValueParameter() {
1831            return parseValueParameter(true);
1832        }
1833    
1834        public void parseValueParameter() {
1835            parseValueParameter(false);
1836        }
1837    
1838        private boolean parseValueParameter(boolean rollbackOnFailure) {
1839            PsiBuilder.Marker parameter = mark();
1840    
1841            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON));
1842    
1843            if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
1844                advance(); // VAR_KEYWORD | VAL_KEYWORD
1845            }
1846    
1847            if (!parseFunctionParameterRest() && rollbackOnFailure) {
1848                parameter.rollbackTo();
1849                return false;
1850            }
1851    
1852            parameter.done(VALUE_PARAMETER);
1853            return true;
1854        }
1855    
1856        /*
1857         * functionParameterRest
1858         *   : parameter ("=" element)?
1859         *   ;
1860         */
1861        private boolean parseFunctionParameterRest() {
1862            boolean noErrors = true;
1863    
1864            // Recovery for the case 'fun foo(Array<String>) {}'
1865            if (at(IDENTIFIER) && lookahead(1) == LT) {
1866                error("Parameter name expected");
1867                parseTypeRef();
1868                noErrors = false;
1869            }
1870            else {
1871                expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
1872    
1873                if (at(COLON)) {
1874                    advance(); // COLON
1875                    parseTypeRef();
1876                }
1877                else {
1878                    errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
1879                    noErrors = false;
1880                }
1881            }
1882    
1883            if (at(EQ)) {
1884                advance(); // EQ
1885                myExpressionParsing.parseExpression();
1886            }
1887    
1888            return noErrors;
1889        }
1890    
1891        @Override
1892        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1893            return createForTopLevel(builder);
1894        }
1895    
1896        /*package*/ static class TokenDetector implements Consumer<IElementType> {
1897    
1898            private boolean detected = false;
1899            private final TokenSet tokens;
1900    
1901            public TokenDetector(JetKeywordToken token) {
1902                this.tokens = TokenSet.create(token);
1903            }
1904    
1905            @Override
1906            public void consume(IElementType item) {
1907                if (tokens.contains(item)) {
1908                    detected = true;
1909                }
1910            }
1911    
1912            public boolean isDetected() {
1913                return detected;
1914            }
1915        }
1916    
1917        static enum AnnotationParsingMode {
1918            FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true),
1919            FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true),
1920            REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS(false, false),
1921            REGULAR_ANNOTATIONS_ALLOW_SHORTS(true, false);
1922    
1923            boolean allowShortAnnotations;
1924            boolean isFileAnnotationParsingMode;
1925    
1926            AnnotationParsingMode(boolean allowShortAnnotations, boolean onlyFileAnnotations) {
1927                this.allowShortAnnotations = allowShortAnnotations;
1928                this.isFileAnnotationParsingMode = onlyFileAnnotations;
1929            }
1930        }
1931    }