001    /*
002     * Copyright 2010-2013 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, FUN_KEYWORD, 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", TokenSet.create(LBRACE, COMMA));
792                initializer.drop();
793                return;
794            }
795            myExpressionParsing.parseValueArgumentList();
796    
797            initializer.done(type);
798        }
799    
800        /*
801         * classObject
802         *   : modifiers "class" object
803         *   ;
804         */
805        private JetNodeType parseClassObject() {
806            assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD;
807    
808            advance(); // CLASS_KEYWORD
809    
810            PsiBuilder.Marker objectDeclaration = mark();
811            parseObject(false, true);
812            objectDeclaration.done(OBJECT_DECLARATION);
813    
814            return CLASS_OBJECT;
815        }
816    
817        /*
818         * typedef
819         *   : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
820         *   ;
821         */
822        JetNodeType parseTypeDef() {
823            assert _at(TYPE_KEYWORD);
824    
825            advance(); // TYPE_KEYWORD
826    
827            expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
828    
829            if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
830                parseTypeConstraints();
831            }
832    
833            expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
834    
835            parseTypeRef();
836    
837            consumeIf(SEMICOLON);
838    
839            return TYPEDEF;
840        }
841    
842        /*
843         * variableDeclarationEntry
844         *   : SimpleName (":" type)?
845         *   ;
846         *
847         * property
848         *   : modifiers ("val" | "var")
849         *       typeParameters? (type "." | annotations)?
850         *       ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
851         *       typeConstraints
852         *       ("by" | "=" expression SEMI?)?
853         *       (getter? setter? | setter? getter?) SEMI?
854         *   ;
855         */
856        private IElementType parseProperty() {
857            return parseProperty(false);
858        }
859    
860        public IElementType parseProperty(boolean local) {
861            if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
862                advance(); // VAL_KEYWORD or VAR_KEYWORD
863            }
864            else {
865                errorAndAdvance("Expecting 'val' or 'var'");
866            }
867    
868            boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
869    
870            TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
871    
872            myBuilder.disableJoiningComplexTokens();
873    
874            // TODO: extract constant
875            int lastDot = matchTokenStreamPredicate(new LastBefore(
876                    new AtSet(DOT, SAFE_ACCESS),
877                    new AbstractTokenStreamPredicate() {
878                        @Override
879                        public boolean matching(boolean topLevel) {
880                            if (topLevel && (at(EQ) || at(COLON))) return true;
881                            if (topLevel && at(IDENTIFIER)) {
882                                IElementType lookahead = lookahead(1);
883                                return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
884                            }
885                            return false;
886                        }
887                    }));
888    
889            PsiBuilder.Marker receiver = mark();
890            parseReceiverType("property", propertyNameFollow, lastDot);
891    
892            boolean multiDeclaration = at(LPAR);
893            boolean receiverTypeDeclared = lastDot != -1;
894    
895            errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
896    
897            if (multiDeclaration) {
898                PsiBuilder.Marker multiDecl = mark();
899                parseMultiDeclarationName(propertyNameFollow);
900                errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
901            }
902            else {
903                parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow);
904            }
905    
906            myBuilder.restoreJoiningComplexTokensState();
907    
908            if (at(COLON)) {
909                PsiBuilder.Marker type = mark();
910                advance(); // COLON
911                parseTypeRef();
912                errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
913            }
914    
915            parseTypeConstraintsGuarded(typeParametersDeclared);
916    
917            if (local) {
918                if (at(BY_KEYWORD)) {
919                    parsePropertyDelegate();
920                }
921                else if (at(EQ)) {
922                    advance(); // EQ
923                    myExpressionParsing.parseExpression();
924                    // "val a = 1; b" must not be an infix call of b on "val ...;"
925                }
926            }
927            else {
928                if (at(BY_KEYWORD)) {
929                    parsePropertyDelegate();
930                    consumeIf(SEMICOLON);
931                }
932                else if (at(EQ)) {
933                    advance(); // EQ
934                    myExpressionParsing.parseExpression();
935                    consumeIf(SEMICOLON);
936                }
937    
938                if (parsePropertyGetterOrSetter()) {
939                    parsePropertyGetterOrSetter();
940                }
941                if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
942                    if (getLastToken() != SEMICOLON) {
943                        errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON));
944                    }
945                }
946                else {
947                    consumeIf(SEMICOLON);
948                }
949            }
950    
951            return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
952        }
953    
954        /*
955         * propertyDelegate
956         *   : "by" expression
957         *   ;
958         */
959        private void parsePropertyDelegate() {
960            assert _at(BY_KEYWORD);
961            PsiBuilder.Marker delegate = mark();
962            advance(); // BY_KEYWORD
963            myExpressionParsing.parseExpression();
964            delegate.done(PROPERTY_DELEGATE);
965        }
966    
967        /*
968         * (SimpleName (":" type)){","}
969         */
970        public void parseMultiDeclarationName(TokenSet follow) {
971            // Parsing multi-name, e.g.
972            //   val (a, b) = foo()
973            myBuilder.disableNewlines();
974            advance(); // LPAR
975    
976            TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
977            if (!atSet(follow)) {
978                while (true) {
979                    if (at(COMMA)) {
980                        errorAndAdvance("Expecting a name");
981                    }
982                    else if (at(RPAR)) {
983                        error("Expecting a name");
984                        break;
985                    }
986                    PsiBuilder.Marker property = mark();
987                    expect(IDENTIFIER, "Expecting a name", recoverySet);
988    
989                    if (at(COLON)) {
990                        advance(); // COLON
991                        parseTypeRef(follow);
992                    }
993                    property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
994    
995                    if (!at(COMMA)) break;
996                    advance(); // COMMA
997                }
998            }
999    
1000            expect(RPAR, "Expecting ')'", follow);
1001            myBuilder.restoreNewlinesState();
1002        }
1003    
1004        /*
1005         * getterOrSetter
1006         *   : modifiers ("get" | "set")
1007         *   :
1008         *        (     "get" "(" ")"
1009         *           |
1010         *              "set" "(" modifiers parameter ")"
1011         *        ) functionBody
1012         *   ;
1013         */
1014        private boolean parsePropertyGetterOrSetter() {
1015            PsiBuilder.Marker getterOrSetter = mark();
1016    
1017            parseModifierList(MODIFIER_LIST, false);
1018    
1019            if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
1020                getterOrSetter.rollbackTo();
1021                return false;
1022            }
1023    
1024            boolean setter = at(SET_KEYWORD);
1025            advance(); // GET_KEYWORD or SET_KEYWORD
1026    
1027            if (!at(LPAR)) {
1028                // Account for Jet-114 (val a : int get {...})
1029                TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1030                if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1031                    errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1032                }
1033                else {
1034                    getterOrSetter.done(PROPERTY_ACCESSOR);
1035                    return true;
1036                }
1037            }
1038    
1039            myBuilder.disableNewlines();
1040            expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1041            if (setter) {
1042                PsiBuilder.Marker parameterList = mark();
1043                PsiBuilder.Marker setterParameter = mark();
1044                parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON));
1045                expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1046    
1047                if (at(COLON)) {
1048                    advance();  // COLON
1049                    parseTypeRef();
1050                }
1051                setterParameter.done(VALUE_PARAMETER);
1052                parameterList.done(VALUE_PARAMETER_LIST);
1053            }
1054            if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON));
1055            expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1056            myBuilder.restoreNewlinesState();
1057    
1058            if (at(COLON)) {
1059                advance();
1060    
1061                parseTypeRef();
1062            }
1063    
1064            parseFunctionBody();
1065    
1066            getterOrSetter.done(PROPERTY_ACCESSOR);
1067    
1068            return true;
1069        }
1070    
1071        /*
1072         * function
1073         *   : modifiers "fun" typeParameters?
1074         *       (type "." | attributes)?
1075         *       SimpleName
1076         *       typeParameters? functionParameters (":" type)?
1077         *       typeConstraints
1078         *       functionBody?
1079         *   ;
1080         */
1081        IElementType parseFunction() {
1082            assert _at(FUN_KEYWORD);
1083    
1084            advance(); // FUN_KEYWORD
1085    
1086            // Recovery for the case of class A { fun| }
1087            if (at(RBRACE)) {
1088                error("Function body expected");
1089                return FUN;
1090            }
1091    
1092            boolean typeParameterListOccurred = false;
1093            if (at(LT)) {
1094                parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
1095                typeParameterListOccurred = true;
1096            }
1097    
1098            myBuilder.disableJoiningComplexTokens();
1099            int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true);
1100    
1101            TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
1102            parseReceiverType("function", functionNameFollow, lastDot);
1103    
1104            parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow);
1105    
1106            myBuilder.restoreJoiningComplexTokensState();
1107    
1108            TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
1109    
1110            if (at(LT)) {
1111                PsiBuilder.Marker error = mark();
1112                parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1113                errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1114                typeParameterListOccurred = true;
1115            }
1116    
1117            if (at(LPAR)) {
1118                parseValueParameterList(false, valueParametersFollow);
1119            }
1120            else {
1121                error("Expecting '('");
1122            }
1123    
1124            if (at(COLON)) {
1125                advance(); // COLON
1126    
1127                parseTypeRef();
1128            }
1129    
1130            parseTypeConstraintsGuarded(typeParameterListOccurred);
1131    
1132            if (at(SEMICOLON)) {
1133                advance(); // SEMICOLON
1134            }
1135            else if (at(EQ) || at(LBRACE)) {
1136                parseFunctionBody();
1137            }
1138    
1139            return FUN;
1140        }
1141    
1142        /*
1143         *   (type "." | attributes)?
1144         */
1145        private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) {
1146            if (lastDot == -1) { // There's no explicit receiver type specified
1147                parseAnnotations(false);
1148            }
1149            else {
1150                createTruncatedBuilder(lastDot).parseTypeRef();
1151    
1152                if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1153                    advance(); // expectation
1154                }
1155                else {
1156                    errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1157                }
1158            }
1159        }
1160    
1161        /*
1162         * IDENTIFIER
1163         */
1164        private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow) {
1165            if (!receiverFound) {
1166                expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow);
1167            }
1168            else {
1169                expect(IDENTIFIER, "Expecting " + title + " name", nameFollow);
1170            }
1171        }
1172    
1173        /*
1174         * functionBody
1175         *   : block
1176         *   : "=" element
1177         *   ;
1178         */
1179        private void parseFunctionBody() {
1180            if (at(LBRACE)) {
1181                parseBlock();
1182            }
1183            else if (at(EQ)) {
1184                advance(); // EQ
1185                myExpressionParsing.parseExpression();
1186                consumeIf(SEMICOLON);
1187            }
1188            else {
1189                errorAndAdvance("Expecting function body");
1190            }
1191        }
1192    
1193        /*
1194         * block
1195         *   : "{" (expressions)* "}"
1196         *   ;
1197         */
1198        void parseBlock() {
1199            PsiBuilder.Marker block = mark();
1200    
1201            myBuilder.enableNewlines();
1202            expect(LBRACE, "Expecting '{' to open a block");
1203    
1204            myExpressionParsing.parseStatements();
1205    
1206            expect(RBRACE, "Expecting '}");
1207            myBuilder.restoreNewlinesState();
1208    
1209            block.done(BLOCK);
1210        }
1211    
1212        /*
1213         * delegationSpecifier{","}
1214         */
1215        /*package*/ void parseDelegationSpecifierList() {
1216            PsiBuilder.Marker list = mark();
1217    
1218            while (true) {
1219                if (at(COMMA)) {
1220                    errorAndAdvance("Expecting a delegation specifier");
1221                    continue;
1222                }
1223                parseDelegationSpecifier();
1224                if (!at(COMMA)) break;
1225                advance(); // COMMA
1226            }
1227    
1228            list.done(DELEGATION_SPECIFIER_LIST);
1229        }
1230    
1231        /*
1232         * attributes delegationSpecifier
1233         *
1234         * delegationSpecifier
1235         *   : constructorInvocation // type and constructor arguments
1236         *   : userType
1237         *   : explicitDelegation
1238         *   ;
1239         *
1240         * explicitDelegation
1241         *   : userType "by" element
1242         *   ;
1243         */
1244        private void parseDelegationSpecifier() {
1245            PsiBuilder.Marker delegator = mark();
1246            parseAnnotations(false);
1247    
1248            PsiBuilder.Marker reference = mark();
1249            parseTypeRef();
1250    
1251            if (at(BY_KEYWORD)) {
1252                reference.drop();
1253                advance(); // BY_KEYWORD
1254                createForByClause(myBuilder).myExpressionParsing.parseExpression();
1255                delegator.done(DELEGATOR_BY);
1256            }
1257            else if (at(LPAR)) {
1258                reference.done(CONSTRUCTOR_CALLEE);
1259                myExpressionParsing.parseValueArgumentList();
1260                delegator.done(DELEGATOR_SUPER_CALL);
1261            }
1262            else {
1263                reference.drop();
1264                delegator.done(DELEGATOR_SUPER_CLASS);
1265            }
1266        }
1267    
1268        /*
1269         * typeParameters
1270         *   : ("<" typeParameter{","} ">"
1271         *   ;
1272         */
1273        private boolean parseTypeParameterList(TokenSet recoverySet) {
1274            boolean result = false;
1275            if (at(LT)) {
1276                PsiBuilder.Marker list = mark();
1277    
1278                myBuilder.disableNewlines();
1279                advance(); // LT
1280    
1281                while (true) {
1282                    if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1283                    parseTypeParameter();
1284    
1285                    if (!at(COMMA)) break;
1286                    advance(); // COMMA
1287                }
1288    
1289                expect(GT, "Missing '>'", recoverySet);
1290                myBuilder.restoreNewlinesState();
1291                result = true;
1292    
1293                list.done(TYPE_PARAMETER_LIST);
1294            }
1295            return result;
1296        }
1297    
1298        /*
1299         * typeConstraints
1300         *   : ("where" typeConstraint{","})?
1301         *   ;
1302         */
1303        private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1304            PsiBuilder.Marker error = mark();
1305            boolean constraints = parseTypeConstraints();
1306            errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1307        }
1308    
1309        private boolean parseTypeConstraints() {
1310            if (at(WHERE_KEYWORD)) {
1311                parseTypeConstraintList();
1312                return true;
1313            }
1314            return false;
1315        }
1316    
1317        /*
1318         * typeConstraint{","}
1319         */
1320        private void parseTypeConstraintList() {
1321            assert _at(WHERE_KEYWORD);
1322    
1323            advance(); // WHERE_KEYWORD
1324    
1325            PsiBuilder.Marker list = mark();
1326    
1327            while (true) {
1328                if (at(COMMA)) errorAndAdvance("Type constraint expected");
1329                parseTypeConstraint();
1330                if (!at(COMMA)) break;
1331                advance(); // COMMA
1332            }
1333    
1334            list.done(TYPE_CONSTRAINT_LIST);
1335        }
1336    
1337        /*
1338         * typeConstraint
1339         *   : attributes SimpleName ":" type
1340         *   : attributes "class" "object" SimpleName ":" type
1341         *   ;
1342         */
1343        private void parseTypeConstraint() {
1344            PsiBuilder.Marker constraint = mark();
1345    
1346            parseAnnotations(false);
1347    
1348            if (at(CLASS_KEYWORD)) {
1349                advance(); // CLASS_KEYWORD
1350    
1351                expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST);
1352    
1353            }
1354    
1355            PsiBuilder.Marker reference = mark();
1356            if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) {
1357                reference.done(REFERENCE_EXPRESSION);
1358            }
1359            else {
1360                reference.drop();
1361            }
1362    
1363            expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
1364    
1365            parseTypeRef();
1366    
1367            constraint.done(TYPE_CONSTRAINT);
1368        }
1369    
1370        /*
1371         * typeParameter
1372         *   : modifiers SimpleName (":" userType)?
1373         *   ;
1374         */
1375        private void parseTypeParameter() {
1376            if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1377                error("Type parameter declaration expected");
1378                return;
1379            }
1380    
1381            PsiBuilder.Marker mark = mark();
1382    
1383            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON));
1384    
1385            expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1386    
1387            if (at(COLON)) {
1388                advance(); // COLON
1389                parseTypeRef();
1390            }
1391    
1392            mark.done(TYPE_PARAMETER);
1393    
1394        }
1395    
1396        /*
1397         * type
1398         *   : attributes typeDescriptor
1399         *
1400         * typeDescriptor
1401         *   : selfType
1402         *   : functionType
1403         *   : userType
1404         *   : tupleType
1405         *   : nullableType
1406         *   ;
1407         *
1408         * nullableType
1409         *   : typeDescriptor "?"
1410         */
1411        void parseTypeRef() {
1412            parseTypeRef(TokenSet.EMPTY);
1413        }
1414    
1415        void parseTypeRef(TokenSet extraRecoverySet) {
1416            PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1417            typeRefMarker.done(TYPE_REFERENCE);
1418        }
1419    
1420        // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1421        // on expression-indicating symbols or not
1422        private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1423            // Disabling token merge is required for cases like
1424            //    Int?.(Foo) -> Bar
1425            // we don't support this case now
1426    //        myBuilder.disableJoiningComplexTokens();
1427            PsiBuilder.Marker typeRefMarker = mark();
1428            parseAnnotations(false);
1429    
1430            if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
1431                parseUserType();
1432            }
1433            else if (at(HASH)) {
1434                parseTupleType();
1435            }
1436            else if (at(LPAR)) {
1437                PsiBuilder.Marker functionOrParenthesizedType = mark();
1438    
1439                // This may be a function parameter list or just a prenthesized type
1440                advance(); // LPAR
1441                parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1442    
1443                if (at(RPAR)) {
1444                    advance(); // RPAR
1445                    if (at(ARROW)) {
1446                        // It's a function type with one parameter specified
1447                        //    (A) -> B
1448                        functionOrParenthesizedType.rollbackTo();
1449                        parseFunctionType();
1450                    }
1451                    else {
1452                        // It's a parenthesized type
1453                        //    (A)
1454                        functionOrParenthesizedType.drop();
1455                    }
1456                }
1457                else {
1458                    // This must be a function type
1459                    //   (A, B) -> C
1460                    // or
1461                    //   (a : A) -> C
1462                    functionOrParenthesizedType.rollbackTo();
1463                    parseFunctionType();
1464                }
1465    
1466            }
1467            else if (at(CAPITALIZED_THIS_KEYWORD)) {
1468                parseSelfType();
1469            }
1470            else {
1471                errorWithRecovery("Type expected",
1472                        TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
1473                                       TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
1474            }
1475    
1476            while (at(QUEST)) {
1477                PsiBuilder.Marker precede = typeRefMarker.precede();
1478    
1479                advance(); // QUEST
1480                typeRefMarker.done(NULLABLE_TYPE);
1481    
1482                typeRefMarker = precede;
1483            }
1484    
1485            if (at(DOT)) {
1486                // This is a receiver for a function type
1487                //  A.(B) -> C
1488                //   ^
1489    
1490                PsiBuilder.Marker functionType = typeRefMarker.precede();
1491                PsiBuilder.Marker receiverType = typeRefMarker.precede();
1492                typeRefMarker.done(TYPE_REFERENCE);
1493                receiverType.done(FUNCTION_TYPE_RECEIVER);
1494    
1495                advance(); // DOT
1496    
1497                if (at(LPAR)) {
1498                    parseFunctionTypeContents().drop();
1499                }
1500                else {
1501                    error("Expecting function type");
1502                }
1503                typeRefMarker = functionType.precede();
1504    
1505                functionType.done(FUNCTION_TYPE);
1506            }
1507    //        myBuilder.restoreJoiningComplexTokensState();
1508            return typeRefMarker;
1509        }
1510    
1511        /*
1512         * userType
1513         *   : ("package" ".")? simpleUserType{"."}
1514         *   ;
1515         */
1516        void parseUserType() {
1517            PsiBuilder.Marker userType = mark();
1518    
1519            if (at(PACKAGE_KEYWORD)) {
1520                advance(); // PACKAGE_KEYWORD
1521                expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER));
1522            }
1523    
1524            PsiBuilder.Marker reference = mark();
1525            while (true) {
1526                if (expect(IDENTIFIER, "Expecting type name", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
1527                    reference.done(REFERENCE_EXPRESSION);
1528                }
1529                else {
1530                    reference.drop();
1531                    break;
1532                }
1533    
1534                parseTypeArgumentList();
1535                if (!at(DOT)) {
1536                    break;
1537                }
1538                if (lookahead(1) == LPAR) {
1539                    // This may be a receiver for a function type
1540                    //   Int.(Int) -> Int
1541                    break;
1542                }
1543    
1544                PsiBuilder.Marker precede = userType.precede();
1545                userType.done(USER_TYPE);
1546                userType = precede;
1547    
1548                advance(); // DOT
1549                reference = mark();
1550            }
1551    
1552            userType.done(USER_TYPE);
1553        }
1554    
1555        /*
1556         * selfType
1557         *   : "This"
1558         *   ;
1559         */
1560        private void parseSelfType() {
1561            assert _at(CAPITALIZED_THIS_KEYWORD);
1562    
1563            PsiBuilder.Marker type = mark();
1564            advance(); // CAPITALIZED_THIS_KEYWORD
1565            type.done(SELF_TYPE);
1566        }
1567    
1568        /*
1569         *  (optionalProjection type){","}
1570         */
1571        private PsiBuilder.Marker parseTypeArgumentList() {
1572            if (!at(LT)) return null;
1573    
1574            PsiBuilder.Marker list = mark();
1575    
1576            tryParseTypeArgumentList(TokenSet.EMPTY);
1577    
1578            list.done(TYPE_ARGUMENT_LIST);
1579            return list;
1580        }
1581    
1582        boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
1583            myBuilder.disableNewlines();
1584            advance(); // LT
1585    
1586            while (true) {
1587                PsiBuilder.Marker projection = mark();
1588    
1589    //            TokenSet lookFor = TokenSet.create(IDENTIFIER);
1590    //            TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
1591    //            parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
1592                // Currently we do not allow annotations
1593                parseModifierList(MODIFIER_LIST, false);
1594    
1595                if (at(MUL)) {
1596                    advance(); // MUL
1597                }
1598                else {
1599                    parseTypeRef(extraRecoverySet);
1600                }
1601                projection.done(TYPE_PROJECTION);
1602                if (!at(COMMA)) break;
1603                advance(); // COMMA
1604            }
1605    
1606            boolean atGT = at(GT);
1607            if (!atGT) {
1608                error("Expecting a '>'");
1609            }
1610            else {
1611                advance(); // GT
1612            }
1613            myBuilder.restoreNewlinesState();
1614            return atGT;
1615        }
1616    
1617        private void parseModifierListWithShortAnnotations(JetNodeType modifierList, TokenSet lookFor, TokenSet stopAt) {
1618            int lastId = findLastBefore(lookFor, stopAt, false);
1619            createTruncatedBuilder(lastId).parseModifierList(modifierList, true);
1620        }
1621    
1622        /*
1623         * tupleType
1624         *   : "#" "(" type{","}? ")"
1625         *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
1626         *   ;
1627         */
1628        @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1629        private void parseTupleType() {
1630            assert _at(HASH);
1631    
1632            PsiBuilder.Marker tuple = mark();
1633    
1634            myBuilder.disableNewlines();
1635            advance(); // HASH
1636            consumeIf(LPAR);
1637    
1638            if (!at(RPAR)) {
1639                while (true) {
1640                    if (at(COLON)) {
1641                        errorAndAdvance("Expecting a name for tuple entry");
1642                    }
1643    
1644                    if (at(IDENTIFIER) && lookahead(1) == COLON) {
1645                        advance(); // IDENTIFIER
1646                        advance(); // COLON
1647                        parseTypeRef();
1648                    }
1649                    else if (TYPE_REF_FIRST.contains(tt())) {
1650                        parseTypeRef();
1651                    }
1652                    else {
1653                        error("Type expected");
1654                        break;
1655                    }
1656                    if (!at(COMMA)) break;
1657                    advance(); // COMMA
1658                }
1659            }
1660    
1661            consumeIf(RPAR);
1662            myBuilder.restoreNewlinesState();
1663    
1664            tuple.error("Tuples are not supported. Use data classes instead.");
1665        }
1666    
1667        /*
1668         * functionType
1669         *   : "(" (parameter | modifiers type){","}? ")" "->" type?
1670         *   ;
1671         */
1672        private void parseFunctionType() {
1673            parseFunctionTypeContents().done(FUNCTION_TYPE);
1674        }
1675    
1676        private PsiBuilder.Marker parseFunctionTypeContents() {
1677            assert _at(LPAR) : tt();
1678            PsiBuilder.Marker functionType = mark();
1679    
1680    //        advance(); // LPAR
1681    //
1682    //        int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false);
1683    //        if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
1684    //            TODO : -1 is a hack?
1685    //            createTruncatedBuilder(lastLPar - 1).parseTypeRef();
1686    //            advance(); // DOT
1687    //        }
1688    
1689            parseValueParameterList(true, TokenSet.EMPTY);
1690    
1691    //        if (at(COLON)) {
1692    //            advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
1693    
1694            expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
1695            parseTypeRef();
1696    //        }
1697    
1698            return functionType;//.done(FUNCTION_TYPE);
1699        }
1700    
1701        /*
1702         * functionParameters
1703         *   : "(" functionParameter{","}? ")" // default values
1704         *   ;
1705         *
1706         * functionParameter
1707         *   : modifiers functionParameterRest
1708         *   ;
1709         *
1710         * functionParameterRest
1711         *   : parameter ("=" element)?
1712         *   ;
1713         */
1714        void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
1715            assert _at(LPAR);
1716            PsiBuilder.Marker parameters = mark();
1717    
1718            myBuilder.disableNewlines();
1719            advance(); // LPAR
1720    
1721            if (!at(RPAR) && !atSet(recoverySet)) {
1722                while (true) {
1723                    if (at(COMMA)) {
1724                        errorAndAdvance("Expecting a parameter declaration");
1725                    }
1726                    else if (at(RPAR)) {
1727                        error("Expecting a parameter declaration");
1728                        break;
1729                    }
1730                    if (isFunctionTypeContents) {
1731                        if (!tryParseValueParameter()) {
1732                            PsiBuilder.Marker valueParameter = mark();
1733                            parseModifierList(MODIFIER_LIST, false); // lazy, out, ref
1734                            parseTypeRef();
1735                            valueParameter.done(VALUE_PARAMETER);
1736                        }
1737                    }
1738                    else {
1739                        parseValueParameter();
1740                    }
1741                    if (at(COMMA)) {
1742                        advance(); // COMMA
1743                    }
1744                    else {
1745                        if (!at(RPAR)) error("Expecting comma or ')'");
1746                        if (!atSet(VALUE_PARAMETER_FIRST)) break;
1747                    }
1748                }
1749            }
1750    
1751            expect(RPAR, "Expecting ')'", recoverySet);
1752            myBuilder.restoreNewlinesState();
1753    
1754            parameters.done(VALUE_PARAMETER_LIST);
1755        }
1756    
1757        /*
1758         * functionParameter
1759         *   : modifiers ("val" | "var")? parameter ("=" element)?
1760         *   ;
1761         */
1762        private boolean tryParseValueParameter() {
1763            return parseValueParameter(true);
1764        }
1765    
1766        public void parseValueParameter() {
1767            parseValueParameter(false);
1768        }
1769    
1770        private boolean parseValueParameter(boolean rollbackOnFailure) {
1771            PsiBuilder.Marker parameter = mark();
1772    
1773            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON));
1774    
1775            if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
1776                advance(); // VAR_KEYWORD | VAL_KEYWORD
1777            }
1778    
1779            if (!parseFunctionParameterRest() && rollbackOnFailure) {
1780                parameter.rollbackTo();
1781                return false;
1782            }
1783    
1784            parameter.done(VALUE_PARAMETER);
1785            return true;
1786        }
1787    
1788        /*
1789         * functionParameterRest
1790         *   : parameter ("=" element)?
1791         *   ;
1792         */
1793        private boolean parseFunctionParameterRest() {
1794            boolean noErrors = true;
1795    
1796            // Recovery for the case 'fun foo(Array<String>) {}'
1797            if (at(IDENTIFIER) && lookahead(1) == LT) {
1798                error("Parameter name expected");
1799                parseTypeRef();
1800                noErrors = false;
1801            }
1802            else {
1803                expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
1804    
1805                if (at(COLON)) {
1806                    advance(); // COLON
1807                    parseTypeRef();
1808                }
1809                else {
1810                    errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
1811                    noErrors = false;
1812                }
1813            }
1814    
1815            if (at(EQ)) {
1816                advance(); // EQ
1817                myExpressionParsing.parseExpression();
1818            }
1819    
1820            return noErrors;
1821        }
1822    
1823        @Override
1824        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1825            return createForTopLevel(builder);
1826        }
1827    
1828        /*package*/ static class TokenDetector implements Consumer<IElementType> {
1829    
1830            private boolean detected = false;
1831            private final TokenSet tokens;
1832    
1833            public TokenDetector(JetKeywordToken token) {
1834                this.tokens = TokenSet.create(token);
1835            }
1836    
1837            @Override
1838            public void consume(IElementType item) {
1839                if (tokens.contains(item)) {
1840                    detected = true;
1841                }
1842            }
1843    
1844            public boolean isDetected() {
1845                return detected;
1846            }
1847        }
1848    }