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