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            if (!parseIdeTemplate()) {
469                expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
470            }
471            boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
472    
473            PsiBuilder.Marker beforeConstructorModifiers = mark();
474            boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false);
475    
476            // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
477            if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON) ) {
478                beforeConstructorModifiers.rollbackTo();
479                return CLASS;
480            }
481    
482            // We are still inside a class declaration
483            beforeConstructorModifiers.drop();
484    
485            if (at(LPAR)) {
486                parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
487            }
488            else if (hasConstructorModifiers) {
489                // A comprehensive error message for cases like:
490                //    class A private : Foo
491                // or
492                //    class A private {
493                error("Expecting primary constructor parameter list");
494            }
495    
496            if (at(COLON)) {
497                advance(); // COLON
498                parseDelegationSpecifierList();
499            }
500    
501            parseTypeConstraintsGuarded(typeParametersDeclared);
502    
503            if (at(LBRACE)) {
504                if (enumClass) {
505                    parseEnumClassBody();
506                }
507                else {
508                    parseClassBody();
509                }
510            }
511    
512            return CLASS;
513        }
514    
515        /*
516         * enumClassBody
517         *   : "{" enumEntry* "}"
518         *   ;
519         */
520        private void parseEnumClassBody() {
521            if (!at(LBRACE)) return;
522    
523            PsiBuilder.Marker classBody = mark();
524    
525            myBuilder.enableNewlines();
526            advance(); // LBRACE
527    
528            if (!parseIdeTemplate()) {
529                while (!eof() && !at(RBRACE)) {
530                    PsiBuilder.Marker entryOrMember = mark();
531    
532                    TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
533                    int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
534                    TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
535                    createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector, false);
536    
537                    IElementType type;
538                    if (at(IDENTIFIER)) {
539                        parseEnumEntry();
540                        type = ENUM_ENTRY;
541                    }
542                    else {
543                        type = parseMemberDeclarationRest(enumDetector.isDetected());
544                    }
545    
546                    if (type == null) {
547                        errorAndAdvance("Expecting an enum entry or member declaration");
548                        entryOrMember.drop();
549                    }
550                    else {
551                        entryOrMember.done(type);
552                    }
553                }
554            }
555    
556            expect(RBRACE, "Expecting '}' to close enum class body");
557            myBuilder.restoreNewlinesState();
558    
559            classBody.done(CLASS_BODY);
560        }
561    
562        /*
563         * enumEntry
564         *   : modifiers SimpleName (":" initializer{","})? classBody?
565         *   ;
566         */
567        private void parseEnumEntry() {
568            assert _at(IDENTIFIER);
569    
570            PsiBuilder.Marker nameAsDeclaration = mark();
571            advance(); // IDENTIFIER
572            nameAsDeclaration.done(OBJECT_DECLARATION_NAME);
573    
574            if (at(COLON)) {
575                advance(); // COLON
576    
577                parseInitializerList();
578            }
579    
580            if (at(LBRACE)) {
581                parseClassBody();
582            }
583    
584            consumeIf(SEMICOLON);
585        }
586    
587        /*
588         * classBody
589         *   : ("{" memberDeclaration "}")?
590         *   ;
591         */
592        /*package*/ void parseClassBody() {
593            PsiBuilder.Marker body = mark();
594    
595            myBuilder.enableNewlines();
596            expect(LBRACE, "Expecting a class body", TokenSet.create(LBRACE));
597    
598            if (!parseIdeTemplate()) {
599                while (!eof()) {
600                    if (at(RBRACE)) {
601                        break;
602                    }
603                    parseMemberDeclaration();
604                }
605            }
606            expect(RBRACE, "Missing '}");
607            myBuilder.restoreNewlinesState();
608    
609            body.done(CLASS_BODY);
610        }
611    
612        /*
613         * memberDeclaration
614         *   : modifiers memberDeclaration'
615         *   ;
616         *
617         * memberDeclaration'
618         *   : classObject
619         *   : constructor
620         *   : function
621         *   : property
622         *   : class
623         *   : extension
624         *   : typedef
625         *   : anonymousInitializer
626         *   : object
627         *   ;
628         */
629        private void parseMemberDeclaration() {
630            PsiBuilder.Marker decl = mark();
631    
632            TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
633            parseModifierList(MODIFIER_LIST, enumDetector, true);
634    
635            IElementType declType = parseMemberDeclarationRest(enumDetector.isDetected());
636    
637            if (declType == null) {
638                errorWithRecovery("Expecting member declaration", TokenSet.create(RBRACE));
639                decl.drop();
640            }
641            else {
642                decl.done(declType);
643            }
644        }
645    
646        private IElementType parseMemberDeclarationRest(boolean isEnum) {
647            IElementType keywordToken = tt();
648            IElementType declType = null;
649            if (keywordToken == CLASS_KEYWORD) {
650                if (lookahead(1) == OBJECT_KEYWORD) {
651                    declType = parseClassObject();
652                }
653                else {
654                    declType = parseClass(isEnum);
655                }
656            }
657            else if (keywordToken == TRAIT_KEYWORD) {
658                declType = parseClass(isEnum);
659            }
660            else if (keywordToken == FUN_KEYWORD) {
661                    declType = parseFunction();
662            }
663            else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
664                declType = parseProperty();
665            }
666            else if (keywordToken == TYPE_KEYWORD) {
667                declType = parseTypeDef();
668            }
669            else if (keywordToken == OBJECT_KEYWORD) {
670                parseObject(true, true);
671                declType = OBJECT_DECLARATION;
672            }
673            else if (keywordToken == LBRACE) {
674                parseBlock();
675                declType = ANONYMOUS_INITIALIZER;
676            }
677            return declType;
678        }
679    
680        /*
681         * object
682         *   : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
683         *   ;
684         */
685        void parseObject(boolean named, boolean optionalBody) {
686            assert _at(OBJECT_KEYWORD);
687    
688            advance(); // OBJECT_KEYWORD
689    
690            if (named) {
691                PsiBuilder.Marker propertyDeclaration = mark();
692                if (!parseIdeTemplate()) {
693                    expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
694                }
695                propertyDeclaration.done(OBJECT_DECLARATION_NAME);
696            }
697            else {
698                if (at(IDENTIFIER)) {
699                    error("An object expression cannot bind a name");
700                }
701            }
702    
703            if (optionalBody) {
704                if (at(COLON)) {
705                    advance(); // COLON
706                    parseDelegationSpecifierList();
707                }
708                if (at(LBRACE)) {
709                    parseClassBody();
710                }
711            }
712            else {
713                if (at(LBRACE)) {
714                    parseClassBody();
715                }
716                else {
717                    expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, PACKAGE_KEYWORD));
718                    parseDelegationSpecifierList();
719                    parseClassBody();
720                }
721            }
722        }
723    
724        /*
725         * initializer{","}
726         */
727        private void parseInitializerList() {
728            PsiBuilder.Marker list = mark();
729            while (true) {
730                if (at(COMMA)) errorAndAdvance("Expecting a this or super constructor call");
731                parseInitializer();
732                if (!at(COMMA)) break;
733                advance(); // COMMA
734            }
735            list.done(INITIALIZER_LIST);
736        }
737    
738        /*
739         * initializer
740         *   : attributes "this" valueArguments
741         *   : attributes constructorInvocation // type parameters may (must?) be omitted
742         *   ;
743         */
744        private void parseInitializer() {
745            PsiBuilder.Marker initializer = mark();
746            parseAnnotations(false);
747    
748            IElementType type;
749            if (at(THIS_KEYWORD)) {
750                PsiBuilder.Marker mark = mark();
751                advance(); // THIS_KEYWORD
752                mark.done(THIS_CONSTRUCTOR_REFERENCE);
753                type = THIS_CALL;
754            }
755            else if (atSet(TYPE_REF_FIRST)) {
756                PsiBuilder.Marker reference = mark();
757                parseTypeRef();
758                reference.done(CONSTRUCTOR_CALLEE);
759                type = DELEGATOR_SUPER_CALL;
760            }
761            else {
762                errorWithRecovery("Expecting constructor call (this(...)) or supertype initializer", TokenSet.create(LBRACE, COMMA));
763                initializer.drop();
764                return;
765            }
766            myExpressionParsing.parseValueArgumentList();
767    
768            initializer.done(type);
769        }
770    
771        /*
772         * classObject
773         *   : modifiers "class" object
774         *   ;
775         */
776        private JetNodeType parseClassObject() {
777            assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD;
778    
779            advance(); // CLASS_KEYWORD
780    
781            PsiBuilder.Marker objectDeclaration = mark();
782            parseObject(false, true);
783            objectDeclaration.done(OBJECT_DECLARATION);
784    
785            return CLASS_OBJECT;
786        }
787    
788        /*
789         * typedef
790         *   : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
791         *   ;
792         */
793        JetNodeType parseTypeDef() {
794            assert _at(TYPE_KEYWORD);
795    
796            advance(); // TYPE_KEYWORD
797    
798            expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
799    
800            if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
801                parseTypeConstraints();
802            }
803    
804            expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
805    
806            parseTypeRef();
807    
808            consumeIf(SEMICOLON);
809    
810            return TYPEDEF;
811        }
812    
813        /*
814         * variableDeclarationEntry
815         *   : SimpleName (":" type)?
816         *   ;
817         *
818         * property
819         *   : modifiers ("val" | "var")
820         *       typeParameters? (type "." | annotations)?
821         *       ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
822         *       typeConstraints
823         *       ("by" | "=" expression SEMI?)?
824         *       (getter? setter? | setter? getter?) SEMI?
825         *   ;
826         */
827        private IElementType parseProperty() {
828            return parseProperty(false);
829        }
830    
831        public IElementType parseProperty(boolean local) {
832            if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
833                advance(); // VAL_KEYWORD or VAR_KEYWORD
834            }
835            else {
836                errorAndAdvance("Expecting 'val' or 'var'");
837            }
838    
839            boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
840    
841            TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
842    
843            myBuilder.disableJoiningComplexTokens();
844    
845            // TODO: extract constant
846            int lastDot = matchTokenStreamPredicate(new LastBefore(
847                    new AtSet(DOT, SAFE_ACCESS),
848                    new AbstractTokenStreamPredicate() {
849                        @Override
850                        public boolean matching(boolean topLevel) {
851                            if (topLevel && (at(EQ) || at(COLON))) return true;
852                            if (topLevel && at(IDENTIFIER)) {
853                                IElementType lookahead = lookahead(1);
854                                return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
855                            }
856                            return false;
857                        }
858                    }));
859    
860            PsiBuilder.Marker receiver = mark();
861            parseReceiverType("property", propertyNameFollow, lastDot);
862    
863            boolean multiDeclaration = at(LPAR);
864            boolean receiverTypeDeclared = lastDot != -1;
865    
866            errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
867    
868            if (multiDeclaration) {
869                PsiBuilder.Marker multiDecl = mark();
870                parseMultiDeclarationName(propertyNameFollow);
871                errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
872            }
873            else {
874                parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow);
875            }
876    
877            myBuilder.restoreJoiningComplexTokensState();
878    
879            if (at(COLON)) {
880                PsiBuilder.Marker type = mark();
881                advance(); // COLON
882                if (!parseIdeTemplate()) {
883                    parseTypeRef();
884                }
885                errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
886            }
887    
888            parseTypeConstraintsGuarded(typeParametersDeclared);
889    
890            if (local) {
891                if (at(BY_KEYWORD)) {
892                    parsePropertyDelegate();
893                }
894                else if (at(EQ)) {
895                    advance(); // EQ
896                    myExpressionParsing.parseExpression();
897                    // "val a = 1; b" must not be an infix call of b on "val ...;"
898                }
899            }
900            else {
901                if (at(BY_KEYWORD)) {
902                    parsePropertyDelegate();
903                    consumeIf(SEMICOLON);
904                }
905                else if (at(EQ)) {
906                    advance(); // EQ
907                    myExpressionParsing.parseExpression();
908                    consumeIf(SEMICOLON);
909                }
910    
911                if (parsePropertyGetterOrSetter()) {
912                    parsePropertyGetterOrSetter();
913                }
914                if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
915                    if (getLastToken() != SEMICOLON) {
916                        errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON));
917                    }
918                }
919                else {
920                    consumeIf(SEMICOLON);
921                }
922            }
923    
924            return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
925        }
926    
927        /*
928         * propertyDelegate
929         *   : "by" expression
930         *   ;
931         */
932        private void parsePropertyDelegate() {
933            assert _at(BY_KEYWORD);
934            PsiBuilder.Marker delegate = mark();
935            advance(); // BY_KEYWORD
936            myExpressionParsing.parseExpression();
937            delegate.done(PROPERTY_DELEGATE);
938        }
939    
940        /*
941         * (SimpleName (":" type)){","}
942         */
943        public void parseMultiDeclarationName(TokenSet follow) {
944            // Parsing multi-name, e.g.
945            //   val (a, b) = foo()
946            myBuilder.disableNewlines();
947            advance(); // LPAR
948    
949            TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
950            if (!atSet(follow)) {
951                while (true) {
952                    if (at(COMMA)) {
953                        errorAndAdvance("Expecting a name");
954                    }
955                    else if (at(RPAR)) {
956                        error("Expecting a name");
957                        break;
958                    }
959                    PsiBuilder.Marker property = mark();
960                    expect(IDENTIFIER, "Expecting a name", recoverySet);
961    
962                    if (at(COLON)) {
963                        advance(); // COLON
964                        parseTypeRef(follow);
965                    }
966                    property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
967    
968                    if (!at(COMMA)) break;
969                    advance(); // COMMA
970                }
971            }
972    
973            expect(RPAR, "Expecting ')'", follow);
974            myBuilder.restoreNewlinesState();
975        }
976    
977        /*
978         * getterOrSetter
979         *   : modifiers ("get" | "set")
980         *   :
981         *        (     "get" "(" ")"
982         *           |
983         *              "set" "(" modifiers parameter ")"
984         *        ) functionBody
985         *   ;
986         */
987        private boolean parsePropertyGetterOrSetter() {
988            PsiBuilder.Marker getterOrSetter = mark();
989    
990            parseModifierList(MODIFIER_LIST, false);
991    
992            if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
993                getterOrSetter.rollbackTo();
994                return false;
995            }
996    
997            boolean setter = at(SET_KEYWORD);
998            advance(); // GET_KEYWORD or SET_KEYWORD
999    
1000            if (!at(LPAR)) {
1001                // Account for Jet-114 (val a : int get {...})
1002                TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1003                if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1004                    errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1005                }
1006                else {
1007                    getterOrSetter.done(PROPERTY_ACCESSOR);
1008                    return true;
1009                }
1010            }
1011    
1012            myBuilder.disableNewlines();
1013            expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1014            if (setter) {
1015                PsiBuilder.Marker parameterList = mark();
1016                PsiBuilder.Marker setterParameter = mark();
1017                parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON));
1018                expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1019    
1020                if (at(COLON)) {
1021                    advance();  // COLON
1022                    parseTypeRef();
1023                }
1024                setterParameter.done(VALUE_PARAMETER);
1025                parameterList.done(VALUE_PARAMETER_LIST);
1026            }
1027            if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON));
1028            expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1029            myBuilder.restoreNewlinesState();
1030    
1031            if (at(COLON)) {
1032                advance();
1033    
1034                parseTypeRef();
1035            }
1036    
1037            parseFunctionBody();
1038    
1039            getterOrSetter.done(PROPERTY_ACCESSOR);
1040    
1041            return true;
1042        }
1043    
1044        /*
1045         * function
1046         *   : modifiers "fun" typeParameters?
1047         *       (type "." | attributes)?
1048         *       SimpleName
1049         *       typeParameters? functionParameters (":" type)?
1050         *       typeConstraints
1051         *       functionBody?
1052         *   ;
1053         */
1054        IElementType parseFunction() {
1055            assert _at(FUN_KEYWORD);
1056    
1057            advance(); // FUN_KEYWORD
1058    
1059            // Recovery for the case of class A { fun| }
1060            if (at(RBRACE)) {
1061                error("Function body expected");
1062                return FUN;
1063            }
1064    
1065            boolean typeParameterListOccurred = false;
1066            if (at(LT)) {
1067                parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
1068                typeParameterListOccurred = true;
1069            }
1070    
1071            myBuilder.disableJoiningComplexTokens();
1072            int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true);
1073    
1074            TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
1075            parseReceiverType("function", functionNameFollow, lastDot);
1076    
1077            parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow);
1078    
1079            myBuilder.restoreJoiningComplexTokensState();
1080    
1081            TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
1082    
1083            if (at(LT)) {
1084                PsiBuilder.Marker error = mark();
1085                parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1086                errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1087                typeParameterListOccurred = true;
1088            }
1089    
1090            if (at(LPAR)) {
1091                parseValueParameterList(false, valueParametersFollow);
1092            }
1093            else {
1094                error("Expecting '('");
1095            }
1096    
1097            if (at(COLON)) {
1098                advance(); // COLON
1099    
1100                if (!parseIdeTemplate()) {
1101                    parseTypeRef();
1102                }
1103            }
1104    
1105            parseTypeConstraintsGuarded(typeParameterListOccurred);
1106    
1107            if (at(SEMICOLON)) {
1108                advance(); // SEMICOLON
1109            }
1110            else if (at(EQ) || at(LBRACE)) {
1111                parseFunctionBody();
1112            }
1113    
1114            return FUN;
1115        }
1116    
1117        /*
1118         *   (type "." | attributes)?
1119         */
1120        private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) {
1121            if (lastDot == -1) { // There's no explicit receiver type specified
1122                parseAnnotations(false);
1123            }
1124            else {
1125                if (parseIdeTemplate()) {
1126                    expect(DOT, "Expecting '.' after receiver template");
1127                }
1128                else {
1129                    createTruncatedBuilder(lastDot).parseTypeRef();
1130    
1131                    if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1132                        advance(); // expectation
1133                    }
1134                    else {
1135                        errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1136                    }
1137                }
1138    
1139            }
1140        }
1141    
1142        /*
1143         * IDENTIFIER
1144         */
1145        private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow) {
1146            if (!receiverFound) {
1147                if (!parseIdeTemplate()) {
1148                    expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow);
1149                }
1150            }
1151            else {
1152                if (!parseIdeTemplate()) {
1153                    expect(IDENTIFIER, "Expecting " + title + " name", nameFollow);
1154                }
1155            }
1156        }
1157    
1158        /*
1159         * functionBody
1160         *   : block
1161         *   : "=" element
1162         *   ;
1163         */
1164        private void parseFunctionBody() {
1165            if (at(LBRACE)) {
1166                parseBlock();
1167            }
1168            else if (at(EQ)) {
1169                advance(); // EQ
1170                myExpressionParsing.parseExpression();
1171                consumeIf(SEMICOLON);
1172            }
1173            else {
1174                errorAndAdvance("Expecting function body");
1175            }
1176        }
1177    
1178        /*
1179         * block
1180         *   : "{" (expressions)* "}"
1181         *   ;
1182         */
1183        void parseBlock() {
1184            PsiBuilder.Marker block = mark();
1185    
1186            myBuilder.enableNewlines();
1187            expect(LBRACE, "Expecting '{' to open a block");
1188    
1189            myExpressionParsing.parseStatements();
1190    
1191            expect(RBRACE, "Expecting '}");
1192            myBuilder.restoreNewlinesState();
1193    
1194            block.done(BLOCK);
1195        }
1196    
1197        /*
1198         * delegationSpecifier{","}
1199         */
1200        /*package*/ void parseDelegationSpecifierList() {
1201            PsiBuilder.Marker list = mark();
1202    
1203            while (true) {
1204                if (at(COMMA)) {
1205                    errorAndAdvance("Expecting a delegation specifier");
1206                    continue;
1207                }
1208                parseDelegationSpecifier();
1209                if (!at(COMMA)) break;
1210                advance(); // COMMA
1211            }
1212    
1213            list.done(DELEGATION_SPECIFIER_LIST);
1214        }
1215    
1216        /*
1217         * attributes delegationSpecifier
1218         *
1219         * delegationSpecifier
1220         *   : constructorInvocation // type and constructor arguments
1221         *   : userType
1222         *   : explicitDelegation
1223         *   ;
1224         *
1225         * explicitDelegation
1226         *   : userType "by" element
1227         *   ;
1228         */
1229        private void parseDelegationSpecifier() {
1230            PsiBuilder.Marker delegator = mark();
1231            parseAnnotations(false);
1232    
1233            PsiBuilder.Marker reference = mark();
1234            parseTypeRef();
1235    
1236            if (at(BY_KEYWORD)) {
1237                reference.drop();
1238                advance(); // BY_KEYWORD
1239                createForByClause(myBuilder).myExpressionParsing.parseExpression();
1240                delegator.done(DELEGATOR_BY);
1241            }
1242            else if (at(LPAR)) {
1243                reference.done(CONSTRUCTOR_CALLEE);
1244                myExpressionParsing.parseValueArgumentList();
1245                delegator.done(DELEGATOR_SUPER_CALL);
1246            }
1247            else {
1248                reference.drop();
1249                delegator.done(DELEGATOR_SUPER_CLASS);
1250            }
1251        }
1252    
1253        /*
1254         * typeParameters
1255         *   : ("<" typeParameter{","} ">"
1256         *   ;
1257         */
1258        private boolean parseTypeParameterList(TokenSet recoverySet) {
1259            PsiBuilder.Marker list = mark();
1260            boolean result = false;
1261            if (at(LT)) {
1262    
1263                myBuilder.disableNewlines();
1264                advance(); // LT
1265    
1266                while (true) {
1267                    if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1268                    parseTypeParameter();
1269    
1270                    if (!at(COMMA)) break;
1271                    advance(); // COMMA
1272                }
1273    
1274                expect(GT, "Missing '>'", recoverySet);
1275                myBuilder.restoreNewlinesState();
1276                result = true;
1277            }
1278            list.done(TYPE_PARAMETER_LIST);
1279            return result;
1280        }
1281    
1282        /*
1283         * typeConstraints
1284         *   : ("where" typeConstraint{","})?
1285         *   ;
1286         */
1287        private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1288            PsiBuilder.Marker error = mark();
1289            boolean constraints = parseTypeConstraints();
1290            errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1291        }
1292    
1293        private boolean parseTypeConstraints() {
1294            if (at(WHERE_KEYWORD)) {
1295                parseTypeConstraintList();
1296                return true;
1297            }
1298            return false;
1299        }
1300    
1301        /*
1302         * typeConstraint{","}
1303         */
1304        private void parseTypeConstraintList() {
1305            assert _at(WHERE_KEYWORD);
1306    
1307            advance(); // WHERE_KEYWORD
1308    
1309            PsiBuilder.Marker list = mark();
1310    
1311            while (true) {
1312                if (at(COMMA)) errorAndAdvance("Type constraint expected");
1313                parseTypeConstraint();
1314                if (!at(COMMA)) break;
1315                advance(); // COMMA
1316            }
1317    
1318            list.done(TYPE_CONSTRAINT_LIST);
1319        }
1320    
1321        /*
1322         * typeConstraint
1323         *   : attributes SimpleName ":" type
1324         *   : attributes "class" "object" SimpleName ":" type
1325         *   ;
1326         */
1327        private void parseTypeConstraint() {
1328            PsiBuilder.Marker constraint = mark();
1329    
1330            parseAnnotations(false);
1331    
1332            if (at(CLASS_KEYWORD)) {
1333                advance(); // CLASS_KEYWORD
1334    
1335                expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST);
1336    
1337            }
1338    
1339            PsiBuilder.Marker reference = mark();
1340            if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) {
1341                reference.done(REFERENCE_EXPRESSION);
1342            }
1343            else {
1344                reference.drop();
1345            }
1346    
1347            expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST);
1348    
1349            parseTypeRef();
1350    
1351            constraint.done(TYPE_CONSTRAINT);
1352        }
1353    
1354        /*
1355         * typeParameter
1356         *   : modifiers SimpleName (":" userType)?
1357         *   ;
1358         */
1359        private void parseTypeParameter() {
1360            if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1361                error("Type parameter declaration expected");
1362                return;
1363            }
1364    
1365            PsiBuilder.Marker mark = mark();
1366    
1367            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON));
1368    
1369            expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1370    
1371            if (at(COLON)) {
1372                advance(); // COLON
1373                parseTypeRef();
1374            }
1375    
1376            mark.done(TYPE_PARAMETER);
1377    
1378        }
1379    
1380        /*
1381         * type
1382         *   : attributes typeDescriptor
1383         *
1384         * typeDescriptor
1385         *   : selfType
1386         *   : functionType
1387         *   : userType
1388         *   : tupleType
1389         *   : nullableType
1390         *   ;
1391         *
1392         * nullableType
1393         *   : typeDescriptor "?"
1394         */
1395        void parseTypeRef() {
1396            parseTypeRef(TokenSet.EMPTY);
1397        }
1398    
1399        void parseTypeRef(TokenSet extraRecoverySet) {
1400            PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1401            typeRefMarker.done(TYPE_REFERENCE);
1402        }
1403    
1404        // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1405        // on expression-indicating symbols or not
1406        private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1407            // Disabling token merge is required for cases like
1408            //    Int?.(Foo) -> Bar
1409            // we don't support this case now
1410    //        myBuilder.disableJoiningComplexTokens();
1411            PsiBuilder.Marker typeRefMarker = mark();
1412            parseAnnotations(false);
1413    
1414            if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
1415                parseUserType();
1416            }
1417            else if (at(HASH)) {
1418                parseTupleType();
1419            }
1420            else if (at(LPAR)) {
1421                PsiBuilder.Marker functionOrParenthesizedType = mark();
1422    
1423                // This may be a function parameter list or just a prenthesized type
1424                advance(); // LPAR
1425                parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1426    
1427                if (at(RPAR)) {
1428                    advance(); // RPAR
1429                    if (at(ARROW)) {
1430                        // It's a function type with one parameter specified
1431                        //    (A) -> B
1432                        functionOrParenthesizedType.rollbackTo();
1433                        parseFunctionType();
1434                    }
1435                    else {
1436                        // It's a parenthesized type
1437                        //    (A)
1438                        functionOrParenthesizedType.drop();
1439                    }
1440                }
1441                else {
1442                    // This must be a function type
1443                    //   (A, B) -> C
1444                    // or
1445                    //   (a : A) -> C
1446                    functionOrParenthesizedType.rollbackTo();
1447                    parseFunctionType();
1448                }
1449    
1450            }
1451            else if (at(CAPITALIZED_THIS_KEYWORD)) {
1452                parseSelfType();
1453            }
1454            else {
1455                errorWithRecovery("Type expected",
1456                        TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
1457                                       TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
1458            }
1459    
1460            while (at(QUEST)) {
1461                PsiBuilder.Marker precede = typeRefMarker.precede();
1462    
1463                advance(); // QUEST
1464                typeRefMarker.done(NULLABLE_TYPE);
1465    
1466                typeRefMarker = precede;
1467            }
1468    
1469            if (at(DOT)) {
1470                // This is a receiver for a function type
1471                //  A.(B) -> C
1472                //   ^
1473    
1474                PsiBuilder.Marker functionType = typeRefMarker.precede();
1475                PsiBuilder.Marker receiverType = typeRefMarker.precede();
1476                typeRefMarker.done(TYPE_REFERENCE);
1477                receiverType.done(FUNCTION_TYPE_RECEIVER);
1478    
1479                advance(); // DOT
1480    
1481                if (at(LPAR)) {
1482                    parseFunctionTypeContents().drop();
1483                }
1484                else {
1485                    error("Expecting function type");
1486                }
1487                typeRefMarker = functionType.precede();
1488    
1489                functionType.done(FUNCTION_TYPE);
1490            }
1491    //        myBuilder.restoreJoiningComplexTokensState();
1492            return typeRefMarker;
1493        }
1494    
1495        /*
1496         * userType
1497         *   : ("namespace" ".")? simpleUserType{"."}
1498         *   ;
1499         */
1500        void parseUserType() {
1501            PsiBuilder.Marker userType = mark();
1502    
1503            if (at(PACKAGE_KEYWORD)) {
1504                advance(); // PACKAGE_KEYWORD
1505                expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER));
1506            }
1507    
1508            PsiBuilder.Marker reference = mark();
1509            while (true) {
1510                if (expect(IDENTIFIER, "Expecting type name", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
1511                    reference.done(REFERENCE_EXPRESSION);
1512                }
1513                else {
1514                    reference.drop();
1515                    break;
1516                }
1517    
1518                parseTypeArgumentList();
1519                if (!at(DOT)) {
1520                    break;
1521                }
1522                if (lookahead(1) == LPAR) {
1523                    // This may be a receiver for a function type
1524                    //   Int.(Int) -> Int
1525                    break;
1526                }
1527    
1528                PsiBuilder.Marker precede = userType.precede();
1529                userType.done(USER_TYPE);
1530                userType = precede;
1531    
1532                advance(); // DOT
1533                reference = mark();
1534            }
1535    
1536            userType.done(USER_TYPE);
1537        }
1538    
1539        /*
1540         * selfType
1541         *   : "This"
1542         *   ;
1543         */
1544        private void parseSelfType() {
1545            assert _at(CAPITALIZED_THIS_KEYWORD);
1546    
1547            PsiBuilder.Marker type = mark();
1548            advance(); // CAPITALIZED_THIS_KEYWORD
1549            type.done(SELF_TYPE);
1550        }
1551    
1552        /*
1553         *  (optionalProjection type){","}
1554         */
1555        private PsiBuilder.Marker parseTypeArgumentList() {
1556            if (!at(LT)) return null;
1557    
1558            PsiBuilder.Marker list = mark();
1559    
1560            tryParseTypeArgumentList(TokenSet.EMPTY);
1561    
1562            list.done(TYPE_ARGUMENT_LIST);
1563            return list;
1564        }
1565    
1566        boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
1567            myBuilder.disableNewlines();
1568            advance(); // LT
1569    
1570            while (true) {
1571                PsiBuilder.Marker projection = mark();
1572    
1573    //            TokenSet lookFor = TokenSet.create(IDENTIFIER);
1574    //            TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
1575    //            parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
1576                // Currently we do not allow annotations
1577                parseModifierList(MODIFIER_LIST, false);
1578    
1579                if (at(MUL)) {
1580                    advance(); // MUL
1581                }
1582                else {
1583                    parseTypeRef(extraRecoverySet);
1584                }
1585                projection.done(TYPE_PROJECTION);
1586                if (!at(COMMA)) break;
1587                advance(); // COMMA
1588            }
1589    
1590            boolean atGT = at(GT);
1591            if (!atGT) {
1592                error("Expecting a '>'");
1593            }
1594            else {
1595                advance(); // GT
1596            }
1597            myBuilder.restoreNewlinesState();
1598            return atGT;
1599        }
1600    
1601        private void parseModifierListWithShortAnnotations(JetNodeType modifierList, TokenSet lookFor, TokenSet stopAt) {
1602            int lastId = findLastBefore(lookFor, stopAt, false);
1603            createTruncatedBuilder(lastId).parseModifierList(modifierList, true);
1604        }
1605    
1606        /*
1607         * tupleType
1608         *   : "#" "(" type{","}? ")"
1609         *   : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility
1610         *   ;
1611         */
1612        @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?)
1613        private void parseTupleType() {
1614            assert _at(HASH);
1615    
1616            PsiBuilder.Marker tuple = mark();
1617    
1618            myBuilder.disableNewlines();
1619            advance(); // HASH
1620            consumeIf(LPAR);
1621    
1622            if (!at(RPAR)) {
1623                while (true) {
1624                    if (at(COLON)) {
1625                        errorAndAdvance("Expecting a name for tuple entry");
1626                    }
1627    
1628                    if (at(IDENTIFIER) && lookahead(1) == COLON) {
1629                        advance(); // IDENTIFIER
1630                        advance(); // COLON
1631                        parseTypeRef();
1632                    }
1633                    else if (TYPE_REF_FIRST.contains(tt())) {
1634                        parseTypeRef();
1635                    }
1636                    else {
1637                        error("Type expected");
1638                        break;
1639                    }
1640                    if (!at(COMMA)) break;
1641                    advance(); // COMMA
1642                }
1643            }
1644    
1645            consumeIf(RPAR);
1646            myBuilder.restoreNewlinesState();
1647    
1648            tuple.error("Tuples are not supported. Use data classes instead.");
1649        }
1650    
1651        /*
1652         * functionType
1653         *   : "(" (parameter | modifiers type){","}? ")" "->" type?
1654         *   ;
1655         */
1656        private void parseFunctionType() {
1657            parseFunctionTypeContents().done(FUNCTION_TYPE);
1658        }
1659    
1660        private PsiBuilder.Marker parseFunctionTypeContents() {
1661            assert _at(LPAR) : tt();
1662            PsiBuilder.Marker functionType = mark();
1663    
1664    //        advance(); // LPAR
1665    //
1666    //        int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false);
1667    //        if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) {
1668    //            TODO : -1 is a hack?
1669    //            createTruncatedBuilder(lastLPar - 1).parseTypeRef();
1670    //            advance(); // DOT
1671    //        }
1672    
1673            parseValueParameterList(true, TokenSet.EMPTY);
1674    
1675    //        if (at(COLON)) {
1676    //            advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
1677    
1678            expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
1679            parseTypeRef();
1680    //        }
1681    
1682            return functionType;//.done(FUNCTION_TYPE);
1683        }
1684    
1685        /*
1686         * functionParameters
1687         *   : "(" functionParameter{","}? ")" // default values
1688         *   ;
1689         *
1690         * functionParameter
1691         *   : modifiers functionParameterRest
1692         *   ;
1693         *
1694         * functionParameterRest
1695         *   : parameter ("=" element)?
1696         *   ;
1697         */
1698        void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
1699            assert _at(LPAR);
1700            PsiBuilder.Marker parameters = mark();
1701    
1702            myBuilder.disableNewlines();
1703            advance(); // LPAR
1704    
1705            if (!parseIdeTemplate()) {
1706                if (!at(RPAR) && !atSet(recoverySet)) {
1707                    while (true) {
1708                        if (at(COMMA)) {
1709                            errorAndAdvance("Expecting a parameter declaration");
1710                        }
1711                        else if (at(RPAR)) {
1712                            error("Expecting a parameter declaration");
1713                            break;
1714                        }
1715                        if (isFunctionTypeContents) {
1716                            if (!tryParseValueParameter()) {
1717                                PsiBuilder.Marker valueParameter = mark();
1718                                parseModifierList(MODIFIER_LIST, false); // lazy, out, ref
1719                                parseTypeRef();
1720                                valueParameter.done(VALUE_PARAMETER);
1721                            }
1722                        }
1723                        else {
1724                            parseValueParameter();
1725                        }
1726                        if (at(COMMA)) {
1727                            advance(); // COMMA
1728                        }
1729                        else if (!atSet(VALUE_PARAMETER_FIRST)) break;
1730                    }
1731                }
1732            }
1733    
1734            expect(RPAR, "Expecting ')'", recoverySet);
1735            myBuilder.restoreNewlinesState();
1736    
1737            parameters.done(VALUE_PARAMETER_LIST);
1738        }
1739    
1740        /*
1741         * functionParameter
1742         *   : modifiers ("val" | "var")? parameter ("=" element)?
1743         *   ;
1744         */
1745        private boolean tryParseValueParameter() {
1746            return parseValueParameter(true);
1747        }
1748    
1749        public void parseValueParameter() {
1750            parseValueParameter(false);
1751        }
1752    
1753        private boolean parseValueParameter(boolean rollbackOnFailure) {
1754            PsiBuilder.Marker parameter = mark();
1755    
1756            parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON));
1757    
1758            if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
1759                advance(); // VAR_KEYWORD | VAL_KEYWORD
1760            }
1761    
1762            if (!parseFunctionParameterRest() && rollbackOnFailure) {
1763                parameter.rollbackTo();
1764                return false;
1765            }
1766    
1767            parameter.done(VALUE_PARAMETER);
1768            return true;
1769        }
1770    
1771        /*
1772         * functionParameterRest
1773         *   : parameter ("=" element)?
1774         *   ;
1775         */
1776        private boolean parseFunctionParameterRest() {
1777            boolean noErrors = true;
1778    
1779            // Recovery for the case 'fun foo(Array<String>) {}'
1780            if (at(IDENTIFIER) && lookahead(1) == LT) {
1781                error("Parameter name expected");
1782                parseTypeRef();
1783                noErrors = false;
1784            }
1785            else {
1786                expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
1787    
1788                if (at(COLON)) {
1789                    advance(); // COLON
1790                    parseTypeRef();
1791                }
1792                else {
1793                    errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
1794                    noErrors = false;
1795                }
1796            }
1797    
1798            if (at(EQ)) {
1799                advance(); // EQ
1800                myExpressionParsing.parseExpression();
1801            }
1802    
1803            return noErrors;
1804        }
1805    
1806        /*
1807        * "<#<" expression ">#>"
1808        */
1809        boolean parseIdeTemplate() {
1810            @Nullable JetNodeType nodeType = IDE_TEMPLATE_EXPRESSION;
1811            if (at(IDE_TEMPLATE_START)) {
1812                PsiBuilder.Marker mark = null;
1813                if (nodeType != null) {
1814                    mark = mark();
1815                }
1816                advance();
1817                expect(IDENTIFIER, "Expecting identifier inside template");
1818                expect(IDE_TEMPLATE_END, "Expecting IDE template end after identifier");
1819                if (nodeType != null) {
1820                    mark.done(nodeType);
1821                }
1822                return true;
1823            }
1824            else {
1825                return false;
1826            }
1827        }
1828    
1829        @Override
1830        protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1831            return createForTopLevel(builder);
1832        }
1833    
1834        /*package*/ static class TokenDetector implements Consumer<IElementType> {
1835    
1836            private boolean detected = false;
1837            private final TokenSet tokens;
1838    
1839            public TokenDetector(JetKeywordToken token) {
1840                this.tokens = TokenSet.create(token);
1841            }
1842    
1843            @Override
1844            public void consume(IElementType item) {
1845                if (tokens.contains(item)) {
1846                    detected = true;
1847                }
1848            }
1849    
1850            public boolean isDetected() {
1851                return detected;
1852            }
1853        }
1854    }