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(JetNodeType 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(JetNodeType 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 JetNodeType 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(JetNodeType 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 }