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