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