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