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