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