001 /* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.jet.lang.parsing; 018 019 import com.intellij.lang.PsiBuilder; 020 import com.intellij.psi.tree.IElementType; 021 import com.intellij.psi.tree.TokenSet; 022 import org.jetbrains.annotations.Nullable; 023 import org.jetbrains.jet.JetNodeType; 024 import org.jetbrains.jet.lexer.JetKeywordToken; 025 026 import java.util.HashMap; 027 import java.util.Map; 028 029 import static org.jetbrains.jet.JetNodeTypes.*; 030 import static org.jetbrains.jet.lexer.JetTokens.*; 031 032 public class JetParsing extends AbstractJetParsing { 033 // TODO: token sets to constants, including derived methods 034 public static final Map<String, IElementType> MODIFIER_KEYWORD_MAP = new HashMap<String, IElementType>(); 035 static { 036 for (IElementType softKeyword : MODIFIER_KEYWORDS.getTypes()) { 037 MODIFIER_KEYWORD_MAP.put(((JetKeywordToken) softKeyword).getValue(), softKeyword); 038 } 039 } 040 041 private static final TokenSet TOPLEVEL_OBJECT_FIRST = TokenSet.create(TYPE_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD, 042 FUN_KEYWORD, VAL_KEYWORD, PACKAGE_KEYWORD); 043 private static final TokenSet ENUM_MEMBER_FIRST = TokenSet.create(TYPE_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD, 044 FUN_KEYWORD, VAL_KEYWORD, IDENTIFIER); 045 046 private static final TokenSet CLASS_NAME_RECOVERY_SET = TokenSet.orSet(TokenSet.create(LT, LPAR, COLON, LBRACE), TOPLEVEL_OBJECT_FIRST); 047 private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, LPAR, COLON, LBRACE, GT); 048 private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR); 049 private static final TokenSet PACKAGE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON); 050 private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON); 051 /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH); 052 private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); 053 private static final TokenSet VALUE_PARAMETER_FIRST = 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", TokenSet.create(LBRACE, COMMA)); 792 initializer.drop(); 793 return; 794 } 795 myExpressionParsing.parseValueArgumentList(); 796 797 initializer.done(type); 798 } 799 800 /* 801 * classObject 802 * : modifiers "class" object 803 * ; 804 */ 805 private JetNodeType parseClassObject() { 806 assert _at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD; 807 808 advance(); // CLASS_KEYWORD 809 810 PsiBuilder.Marker objectDeclaration = mark(); 811 parseObject(false, true); 812 objectDeclaration.done(OBJECT_DECLARATION); 813 814 return CLASS_OBJECT; 815 } 816 817 /* 818 * typedef 819 * : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type 820 * ; 821 */ 822 JetNodeType parseTypeDef() { 823 assert _at(TYPE_KEYWORD); 824 825 advance(); // TYPE_KEYWORD 826 827 expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST)); 828 829 if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) { 830 parseTypeConstraints(); 831 } 832 833 expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON))); 834 835 parseTypeRef(); 836 837 consumeIf(SEMICOLON); 838 839 return TYPEDEF; 840 } 841 842 /* 843 * variableDeclarationEntry 844 * : SimpleName (":" type)? 845 * ; 846 * 847 * property 848 * : modifiers ("val" | "var") 849 * typeParameters? (type "." | annotations)? 850 * ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry) 851 * typeConstraints 852 * ("by" | "=" expression SEMI?)? 853 * (getter? setter? | setter? getter?) SEMI? 854 * ; 855 */ 856 private IElementType parseProperty() { 857 return parseProperty(false); 858 } 859 860 public IElementType parseProperty(boolean local) { 861 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) { 862 advance(); // VAL_KEYWORD or VAR_KEYWORD 863 } 864 else { 865 errorAndAdvance("Expecting 'val' or 'var'"); 866 } 867 868 boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON)); 869 870 TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD); 871 872 myBuilder.disableJoiningComplexTokens(); 873 874 // TODO: extract constant 875 int lastDot = matchTokenStreamPredicate(new LastBefore( 876 new AtSet(DOT, SAFE_ACCESS), 877 new AbstractTokenStreamPredicate() { 878 @Override 879 public boolean matching(boolean topLevel) { 880 if (topLevel && (at(EQ) || at(COLON))) return true; 881 if (topLevel && at(IDENTIFIER)) { 882 IElementType lookahead = lookahead(1); 883 return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST; 884 } 885 return false; 886 } 887 })); 888 889 PsiBuilder.Marker receiver = mark(); 890 parseReceiverType("property", propertyNameFollow, lastDot); 891 892 boolean multiDeclaration = at(LPAR); 893 boolean receiverTypeDeclared = lastDot != -1; 894 895 errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration"); 896 897 if (multiDeclaration) { 898 PsiBuilder.Marker multiDecl = mark(); 899 parseMultiDeclarationName(propertyNameFollow); 900 errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values"); 901 } 902 else { 903 parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow); 904 } 905 906 myBuilder.restoreJoiningComplexTokensState(); 907 908 if (at(COLON)) { 909 PsiBuilder.Marker type = mark(); 910 advance(); // COLON 911 parseTypeRef(); 912 errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations"); 913 } 914 915 parseTypeConstraintsGuarded(typeParametersDeclared); 916 917 if (local) { 918 if (at(BY_KEYWORD)) { 919 parsePropertyDelegate(); 920 } 921 else if (at(EQ)) { 922 advance(); // EQ 923 myExpressionParsing.parseExpression(); 924 // "val a = 1; b" must not be an infix call of b on "val ...;" 925 } 926 } 927 else { 928 if (at(BY_KEYWORD)) { 929 parsePropertyDelegate(); 930 consumeIf(SEMICOLON); 931 } 932 else if (at(EQ)) { 933 advance(); // EQ 934 myExpressionParsing.parseExpression(); 935 consumeIf(SEMICOLON); 936 } 937 938 if (parsePropertyGetterOrSetter()) { 939 parsePropertyGetterOrSetter(); 940 } 941 if (!atSet(EOL_OR_SEMICOLON, RBRACE)) { 942 if (getLastToken() != SEMICOLON) { 943 errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON)); 944 } 945 } 946 else { 947 consumeIf(SEMICOLON); 948 } 949 } 950 951 return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY; 952 } 953 954 /* 955 * propertyDelegate 956 * : "by" expression 957 * ; 958 */ 959 private void parsePropertyDelegate() { 960 assert _at(BY_KEYWORD); 961 PsiBuilder.Marker delegate = mark(); 962 advance(); // BY_KEYWORD 963 myExpressionParsing.parseExpression(); 964 delegate.done(PROPERTY_DELEGATE); 965 } 966 967 /* 968 * (SimpleName (":" type)){","} 969 */ 970 public void parseMultiDeclarationName(TokenSet follow) { 971 // Parsing multi-name, e.g. 972 // val (a, b) = foo() 973 myBuilder.disableNewlines(); 974 advance(); // LPAR 975 976 TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow); 977 if (!atSet(follow)) { 978 while (true) { 979 if (at(COMMA)) { 980 errorAndAdvance("Expecting a name"); 981 } 982 else if (at(RPAR)) { 983 error("Expecting a name"); 984 break; 985 } 986 PsiBuilder.Marker property = mark(); 987 expect(IDENTIFIER, "Expecting a name", recoverySet); 988 989 if (at(COLON)) { 990 advance(); // COLON 991 parseTypeRef(follow); 992 } 993 property.done(MULTI_VARIABLE_DECLARATION_ENTRY); 994 995 if (!at(COMMA)) break; 996 advance(); // COMMA 997 } 998 } 999 1000 expect(RPAR, "Expecting ')'", follow); 1001 myBuilder.restoreNewlinesState(); 1002 } 1003 1004 /* 1005 * getterOrSetter 1006 * : modifiers ("get" | "set") 1007 * : 1008 * ( "get" "(" ")" 1009 * | 1010 * "set" "(" modifiers parameter ")" 1011 * ) functionBody 1012 * ; 1013 */ 1014 private boolean parsePropertyGetterOrSetter() { 1015 PsiBuilder.Marker getterOrSetter = mark(); 1016 1017 parseModifierList(MODIFIER_LIST, false); 1018 1019 if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) { 1020 getterOrSetter.rollbackTo(); 1021 return false; 1022 } 1023 1024 boolean setter = at(SET_KEYWORD); 1025 advance(); // GET_KEYWORD or SET_KEYWORD 1026 1027 if (!at(LPAR)) { 1028 // Account for Jet-114 (val a : int get {...}) 1029 TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(LBRACKET, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE)); 1030 if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) { 1031 errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ))); 1032 } 1033 else { 1034 getterOrSetter.done(PROPERTY_ACCESSOR); 1035 return true; 1036 } 1037 } 1038 1039 myBuilder.disableNewlines(); 1040 expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ)); 1041 if (setter) { 1042 PsiBuilder.Marker parameterList = mark(); 1043 PsiBuilder.Marker setterParameter = mark(); 1044 parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON)); 1045 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ)); 1046 1047 if (at(COLON)) { 1048 advance(); // COLON 1049 parseTypeRef(); 1050 } 1051 setterParameter.done(VALUE_PARAMETER); 1052 parameterList.done(VALUE_PARAMETER_LIST); 1053 } 1054 if (!at(RPAR)) errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ, EOL_OR_SEMICOLON)); 1055 expect(RPAR, "Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, EQ)); 1056 myBuilder.restoreNewlinesState(); 1057 1058 if (at(COLON)) { 1059 advance(); 1060 1061 parseTypeRef(); 1062 } 1063 1064 parseFunctionBody(); 1065 1066 getterOrSetter.done(PROPERTY_ACCESSOR); 1067 1068 return true; 1069 } 1070 1071 /* 1072 * function 1073 * : modifiers "fun" typeParameters? 1074 * (type "." | attributes)? 1075 * SimpleName 1076 * typeParameters? functionParameters (":" type)? 1077 * typeConstraints 1078 * functionBody? 1079 * ; 1080 */ 1081 IElementType parseFunction() { 1082 assert _at(FUN_KEYWORD); 1083 1084 advance(); // FUN_KEYWORD 1085 1086 // Recovery for the case of class A { fun| } 1087 if (at(RBRACE)) { 1088 error("Function body expected"); 1089 return FUN; 1090 } 1091 1092 boolean typeParameterListOccurred = false; 1093 if (at(LT)) { 1094 parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR)); 1095 typeParameterListOccurred = true; 1096 } 1097 1098 myBuilder.disableJoiningComplexTokens(); 1099 int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true); 1100 1101 TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ); 1102 parseReceiverType("function", functionNameFollow, lastDot); 1103 1104 parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow); 1105 1106 myBuilder.restoreJoiningComplexTokensState(); 1107 1108 TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR); 1109 1110 if (at(LT)) { 1111 PsiBuilder.Marker error = mark(); 1112 parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow)); 1113 errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function"); 1114 typeParameterListOccurred = true; 1115 } 1116 1117 if (at(LPAR)) { 1118 parseValueParameterList(false, valueParametersFollow); 1119 } 1120 else { 1121 error("Expecting '('"); 1122 } 1123 1124 if (at(COLON)) { 1125 advance(); // COLON 1126 1127 parseTypeRef(); 1128 } 1129 1130 parseTypeConstraintsGuarded(typeParameterListOccurred); 1131 1132 if (at(SEMICOLON)) { 1133 advance(); // SEMICOLON 1134 } 1135 else if (at(EQ) || at(LBRACE)) { 1136 parseFunctionBody(); 1137 } 1138 1139 return FUN; 1140 } 1141 1142 /* 1143 * (type "." | attributes)? 1144 */ 1145 private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) { 1146 if (lastDot == -1) { // There's no explicit receiver type specified 1147 parseAnnotations(false); 1148 } 1149 else { 1150 createTruncatedBuilder(lastDot).parseTypeRef(); 1151 1152 if (atSet(RECEIVER_TYPE_TERMINATORS)) { 1153 advance(); // expectation 1154 } 1155 else { 1156 errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow); 1157 } 1158 } 1159 } 1160 1161 /* 1162 * IDENTIFIER 1163 */ 1164 private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow) { 1165 if (!receiverFound) { 1166 expect(IDENTIFIER, "Expecting " + title + " name or receiver type", nameFollow); 1167 } 1168 else { 1169 expect(IDENTIFIER, "Expecting " + title + " name", nameFollow); 1170 } 1171 } 1172 1173 /* 1174 * functionBody 1175 * : block 1176 * : "=" element 1177 * ; 1178 */ 1179 private void parseFunctionBody() { 1180 if (at(LBRACE)) { 1181 parseBlock(); 1182 } 1183 else if (at(EQ)) { 1184 advance(); // EQ 1185 myExpressionParsing.parseExpression(); 1186 consumeIf(SEMICOLON); 1187 } 1188 else { 1189 errorAndAdvance("Expecting function body"); 1190 } 1191 } 1192 1193 /* 1194 * block 1195 * : "{" (expressions)* "}" 1196 * ; 1197 */ 1198 void parseBlock() { 1199 PsiBuilder.Marker block = mark(); 1200 1201 myBuilder.enableNewlines(); 1202 expect(LBRACE, "Expecting '{' to open a block"); 1203 1204 myExpressionParsing.parseStatements(); 1205 1206 expect(RBRACE, "Expecting '}"); 1207 myBuilder.restoreNewlinesState(); 1208 1209 block.done(BLOCK); 1210 } 1211 1212 /* 1213 * delegationSpecifier{","} 1214 */ 1215 /*package*/ void parseDelegationSpecifierList() { 1216 PsiBuilder.Marker list = mark(); 1217 1218 while (true) { 1219 if (at(COMMA)) { 1220 errorAndAdvance("Expecting a delegation specifier"); 1221 continue; 1222 } 1223 parseDelegationSpecifier(); 1224 if (!at(COMMA)) break; 1225 advance(); // COMMA 1226 } 1227 1228 list.done(DELEGATION_SPECIFIER_LIST); 1229 } 1230 1231 /* 1232 * attributes delegationSpecifier 1233 * 1234 * delegationSpecifier 1235 * : constructorInvocation // type and constructor arguments 1236 * : userType 1237 * : explicitDelegation 1238 * ; 1239 * 1240 * explicitDelegation 1241 * : userType "by" element 1242 * ; 1243 */ 1244 private void parseDelegationSpecifier() { 1245 PsiBuilder.Marker delegator = mark(); 1246 parseAnnotations(false); 1247 1248 PsiBuilder.Marker reference = mark(); 1249 parseTypeRef(); 1250 1251 if (at(BY_KEYWORD)) { 1252 reference.drop(); 1253 advance(); // BY_KEYWORD 1254 createForByClause(myBuilder).myExpressionParsing.parseExpression(); 1255 delegator.done(DELEGATOR_BY); 1256 } 1257 else if (at(LPAR)) { 1258 reference.done(CONSTRUCTOR_CALLEE); 1259 myExpressionParsing.parseValueArgumentList(); 1260 delegator.done(DELEGATOR_SUPER_CALL); 1261 } 1262 else { 1263 reference.drop(); 1264 delegator.done(DELEGATOR_SUPER_CLASS); 1265 } 1266 } 1267 1268 /* 1269 * typeParameters 1270 * : ("<" typeParameter{","} ">" 1271 * ; 1272 */ 1273 private boolean parseTypeParameterList(TokenSet recoverySet) { 1274 boolean result = false; 1275 if (at(LT)) { 1276 PsiBuilder.Marker list = mark(); 1277 1278 myBuilder.disableNewlines(); 1279 advance(); // LT 1280 1281 while (true) { 1282 if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration"); 1283 parseTypeParameter(); 1284 1285 if (!at(COMMA)) break; 1286 advance(); // COMMA 1287 } 1288 1289 expect(GT, "Missing '>'", recoverySet); 1290 myBuilder.restoreNewlinesState(); 1291 result = true; 1292 1293 list.done(TYPE_PARAMETER_LIST); 1294 } 1295 return result; 1296 } 1297 1298 /* 1299 * typeConstraints 1300 * : ("where" typeConstraint{","})? 1301 * ; 1302 */ 1303 private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) { 1304 PsiBuilder.Marker error = mark(); 1305 boolean constraints = parseTypeConstraints(); 1306 errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared"); 1307 } 1308 1309 private boolean parseTypeConstraints() { 1310 if (at(WHERE_KEYWORD)) { 1311 parseTypeConstraintList(); 1312 return true; 1313 } 1314 return false; 1315 } 1316 1317 /* 1318 * typeConstraint{","} 1319 */ 1320 private void parseTypeConstraintList() { 1321 assert _at(WHERE_KEYWORD); 1322 1323 advance(); // WHERE_KEYWORD 1324 1325 PsiBuilder.Marker list = mark(); 1326 1327 while (true) { 1328 if (at(COMMA)) errorAndAdvance("Type constraint expected"); 1329 parseTypeConstraint(); 1330 if (!at(COMMA)) break; 1331 advance(); // COMMA 1332 } 1333 1334 list.done(TYPE_CONSTRAINT_LIST); 1335 } 1336 1337 /* 1338 * typeConstraint 1339 * : attributes SimpleName ":" type 1340 * : attributes "class" "object" SimpleName ":" type 1341 * ; 1342 */ 1343 private void parseTypeConstraint() { 1344 PsiBuilder.Marker constraint = mark(); 1345 1346 parseAnnotations(false); 1347 1348 if (at(CLASS_KEYWORD)) { 1349 advance(); // CLASS_KEYWORD 1350 1351 expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST); 1352 1353 } 1354 1355 PsiBuilder.Marker reference = mark(); 1356 if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) { 1357 reference.done(REFERENCE_EXPRESSION); 1358 } 1359 else { 1360 reference.drop(); 1361 } 1362 1363 expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST); 1364 1365 parseTypeRef(); 1366 1367 constraint.done(TYPE_CONSTRAINT); 1368 } 1369 1370 /* 1371 * typeParameter 1372 * : modifiers SimpleName (":" userType)? 1373 * ; 1374 */ 1375 private void parseTypeParameter() { 1376 if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) { 1377 error("Type parameter declaration expected"); 1378 return; 1379 } 1380 1381 PsiBuilder.Marker mark = mark(); 1382 1383 parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON)); 1384 1385 expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY); 1386 1387 if (at(COLON)) { 1388 advance(); // COLON 1389 parseTypeRef(); 1390 } 1391 1392 mark.done(TYPE_PARAMETER); 1393 1394 } 1395 1396 /* 1397 * type 1398 * : attributes typeDescriptor 1399 * 1400 * typeDescriptor 1401 * : selfType 1402 * : functionType 1403 * : userType 1404 * : tupleType 1405 * : nullableType 1406 * ; 1407 * 1408 * nullableType 1409 * : typeDescriptor "?" 1410 */ 1411 void parseTypeRef() { 1412 parseTypeRef(TokenSet.EMPTY); 1413 } 1414 1415 void parseTypeRef(TokenSet extraRecoverySet) { 1416 PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet); 1417 typeRefMarker.done(TYPE_REFERENCE); 1418 } 1419 1420 // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop 1421 // on expression-indicating symbols or not 1422 private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) { 1423 // Disabling token merge is required for cases like 1424 // Int?.(Foo) -> Bar 1425 // we don't support this case now 1426 // myBuilder.disableJoiningComplexTokens(); 1427 PsiBuilder.Marker typeRefMarker = mark(); 1428 parseAnnotations(false); 1429 1430 if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) { 1431 parseUserType(); 1432 } 1433 else if (at(HASH)) { 1434 parseTupleType(); 1435 } 1436 else if (at(LPAR)) { 1437 PsiBuilder.Marker functionOrParenthesizedType = mark(); 1438 1439 // This may be a function parameter list or just a prenthesized type 1440 advance(); // LPAR 1441 parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed 1442 1443 if (at(RPAR)) { 1444 advance(); // RPAR 1445 if (at(ARROW)) { 1446 // It's a function type with one parameter specified 1447 // (A) -> B 1448 functionOrParenthesizedType.rollbackTo(); 1449 parseFunctionType(); 1450 } 1451 else { 1452 // It's a parenthesized type 1453 // (A) 1454 functionOrParenthesizedType.drop(); 1455 } 1456 } 1457 else { 1458 // This must be a function type 1459 // (A, B) -> C 1460 // or 1461 // (a : A) -> C 1462 functionOrParenthesizedType.rollbackTo(); 1463 parseFunctionType(); 1464 } 1465 1466 } 1467 else if (at(CAPITALIZED_THIS_KEYWORD)) { 1468 parseSelfType(); 1469 } 1470 else { 1471 errorWithRecovery("Type expected", 1472 TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, 1473 TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet)); 1474 } 1475 1476 while (at(QUEST)) { 1477 PsiBuilder.Marker precede = typeRefMarker.precede(); 1478 1479 advance(); // QUEST 1480 typeRefMarker.done(NULLABLE_TYPE); 1481 1482 typeRefMarker = precede; 1483 } 1484 1485 if (at(DOT)) { 1486 // This is a receiver for a function type 1487 // A.(B) -> C 1488 // ^ 1489 1490 PsiBuilder.Marker functionType = typeRefMarker.precede(); 1491 PsiBuilder.Marker receiverType = typeRefMarker.precede(); 1492 typeRefMarker.done(TYPE_REFERENCE); 1493 receiverType.done(FUNCTION_TYPE_RECEIVER); 1494 1495 advance(); // DOT 1496 1497 if (at(LPAR)) { 1498 parseFunctionTypeContents().drop(); 1499 } 1500 else { 1501 error("Expecting function type"); 1502 } 1503 typeRefMarker = functionType.precede(); 1504 1505 functionType.done(FUNCTION_TYPE); 1506 } 1507 // myBuilder.restoreJoiningComplexTokensState(); 1508 return typeRefMarker; 1509 } 1510 1511 /* 1512 * userType 1513 * : ("package" ".")? simpleUserType{"."} 1514 * ; 1515 */ 1516 void parseUserType() { 1517 PsiBuilder.Marker userType = mark(); 1518 1519 if (at(PACKAGE_KEYWORD)) { 1520 advance(); // PACKAGE_KEYWORD 1521 expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER)); 1522 } 1523 1524 PsiBuilder.Marker reference = mark(); 1525 while (true) { 1526 if (expect(IDENTIFIER, "Expecting type name", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) { 1527 reference.done(REFERENCE_EXPRESSION); 1528 } 1529 else { 1530 reference.drop(); 1531 break; 1532 } 1533 1534 parseTypeArgumentList(); 1535 if (!at(DOT)) { 1536 break; 1537 } 1538 if (lookahead(1) == LPAR) { 1539 // This may be a receiver for a function type 1540 // Int.(Int) -> Int 1541 break; 1542 } 1543 1544 PsiBuilder.Marker precede = userType.precede(); 1545 userType.done(USER_TYPE); 1546 userType = precede; 1547 1548 advance(); // DOT 1549 reference = mark(); 1550 } 1551 1552 userType.done(USER_TYPE); 1553 } 1554 1555 /* 1556 * selfType 1557 * : "This" 1558 * ; 1559 */ 1560 private void parseSelfType() { 1561 assert _at(CAPITALIZED_THIS_KEYWORD); 1562 1563 PsiBuilder.Marker type = mark(); 1564 advance(); // CAPITALIZED_THIS_KEYWORD 1565 type.done(SELF_TYPE); 1566 } 1567 1568 /* 1569 * (optionalProjection type){","} 1570 */ 1571 private PsiBuilder.Marker parseTypeArgumentList() { 1572 if (!at(LT)) return null; 1573 1574 PsiBuilder.Marker list = mark(); 1575 1576 tryParseTypeArgumentList(TokenSet.EMPTY); 1577 1578 list.done(TYPE_ARGUMENT_LIST); 1579 return list; 1580 } 1581 1582 boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) { 1583 myBuilder.disableNewlines(); 1584 advance(); // LT 1585 1586 while (true) { 1587 PsiBuilder.Marker projection = mark(); 1588 1589 // TokenSet lookFor = TokenSet.create(IDENTIFIER); 1590 // TokenSet stopAt = TokenSet.create(COMMA, COLON, GT); 1591 // parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt); 1592 // Currently we do not allow annotations 1593 parseModifierList(MODIFIER_LIST, false); 1594 1595 if (at(MUL)) { 1596 advance(); // MUL 1597 } 1598 else { 1599 parseTypeRef(extraRecoverySet); 1600 } 1601 projection.done(TYPE_PROJECTION); 1602 if (!at(COMMA)) break; 1603 advance(); // COMMA 1604 } 1605 1606 boolean atGT = at(GT); 1607 if (!atGT) { 1608 error("Expecting a '>'"); 1609 } 1610 else { 1611 advance(); // GT 1612 } 1613 myBuilder.restoreNewlinesState(); 1614 return atGT; 1615 } 1616 1617 private void parseModifierListWithShortAnnotations(JetNodeType modifierList, TokenSet lookFor, TokenSet stopAt) { 1618 int lastId = findLastBefore(lookFor, stopAt, false); 1619 createTruncatedBuilder(lastId).parseModifierList(modifierList, true); 1620 } 1621 1622 /* 1623 * tupleType 1624 * : "#" "(" type{","}? ")" 1625 * : "#" "(" parameter{","} ")" // tuple with named entries, the names do not affect assignment compatibility 1626 * ; 1627 */ 1628 @Deprecated // Tuples are dropped, but parsing is left to minimize surprising. This code should be removed some time (in Kotlin 1.0?) 1629 private void parseTupleType() { 1630 assert _at(HASH); 1631 1632 PsiBuilder.Marker tuple = mark(); 1633 1634 myBuilder.disableNewlines(); 1635 advance(); // HASH 1636 consumeIf(LPAR); 1637 1638 if (!at(RPAR)) { 1639 while (true) { 1640 if (at(COLON)) { 1641 errorAndAdvance("Expecting a name for tuple entry"); 1642 } 1643 1644 if (at(IDENTIFIER) && lookahead(1) == COLON) { 1645 advance(); // IDENTIFIER 1646 advance(); // COLON 1647 parseTypeRef(); 1648 } 1649 else if (TYPE_REF_FIRST.contains(tt())) { 1650 parseTypeRef(); 1651 } 1652 else { 1653 error("Type expected"); 1654 break; 1655 } 1656 if (!at(COMMA)) break; 1657 advance(); // COMMA 1658 } 1659 } 1660 1661 consumeIf(RPAR); 1662 myBuilder.restoreNewlinesState(); 1663 1664 tuple.error("Tuples are not supported. Use data classes instead."); 1665 } 1666 1667 /* 1668 * functionType 1669 * : "(" (parameter | modifiers type){","}? ")" "->" type? 1670 * ; 1671 */ 1672 private void parseFunctionType() { 1673 parseFunctionTypeContents().done(FUNCTION_TYPE); 1674 } 1675 1676 private PsiBuilder.Marker parseFunctionTypeContents() { 1677 assert _at(LPAR) : tt(); 1678 PsiBuilder.Marker functionType = mark(); 1679 1680 // advance(); // LPAR 1681 // 1682 // int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false); 1683 // if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) { 1684 // TODO : -1 is a hack? 1685 // createTruncatedBuilder(lastLPar - 1).parseTypeRef(); 1686 // advance(); // DOT 1687 // } 1688 1689 parseValueParameterList(true, TokenSet.EMPTY); 1690 1691 // if (at(COLON)) { 1692 // advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST); 1693 1694 expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST); 1695 parseTypeRef(); 1696 // } 1697 1698 return functionType;//.done(FUNCTION_TYPE); 1699 } 1700 1701 /* 1702 * functionParameters 1703 * : "(" functionParameter{","}? ")" // default values 1704 * ; 1705 * 1706 * functionParameter 1707 * : modifiers functionParameterRest 1708 * ; 1709 * 1710 * functionParameterRest 1711 * : parameter ("=" element)? 1712 * ; 1713 */ 1714 void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) { 1715 assert _at(LPAR); 1716 PsiBuilder.Marker parameters = mark(); 1717 1718 myBuilder.disableNewlines(); 1719 advance(); // LPAR 1720 1721 if (!at(RPAR) && !atSet(recoverySet)) { 1722 while (true) { 1723 if (at(COMMA)) { 1724 errorAndAdvance("Expecting a parameter declaration"); 1725 } 1726 else if (at(RPAR)) { 1727 error("Expecting a parameter declaration"); 1728 break; 1729 } 1730 if (isFunctionTypeContents) { 1731 if (!tryParseValueParameter()) { 1732 PsiBuilder.Marker valueParameter = mark(); 1733 parseModifierList(MODIFIER_LIST, false); // lazy, out, ref 1734 parseTypeRef(); 1735 valueParameter.done(VALUE_PARAMETER); 1736 } 1737 } 1738 else { 1739 parseValueParameter(); 1740 } 1741 if (at(COMMA)) { 1742 advance(); // COMMA 1743 } 1744 else { 1745 if (!at(RPAR)) error("Expecting comma or ')'"); 1746 if (!atSet(VALUE_PARAMETER_FIRST)) break; 1747 } 1748 } 1749 } 1750 1751 expect(RPAR, "Expecting ')'", recoverySet); 1752 myBuilder.restoreNewlinesState(); 1753 1754 parameters.done(VALUE_PARAMETER_LIST); 1755 } 1756 1757 /* 1758 * functionParameter 1759 * : modifiers ("val" | "var")? parameter ("=" element)? 1760 * ; 1761 */ 1762 private boolean tryParseValueParameter() { 1763 return parseValueParameter(true); 1764 } 1765 1766 public void parseValueParameter() { 1767 parseValueParameter(false); 1768 } 1769 1770 private boolean parseValueParameter(boolean rollbackOnFailure) { 1771 PsiBuilder.Marker parameter = mark(); 1772 1773 parseModifierListWithShortAnnotations(MODIFIER_LIST, TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON)); 1774 1775 if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { 1776 advance(); // VAR_KEYWORD | VAL_KEYWORD 1777 } 1778 1779 if (!parseFunctionParameterRest() && rollbackOnFailure) { 1780 parameter.rollbackTo(); 1781 return false; 1782 } 1783 1784 parameter.done(VALUE_PARAMETER); 1785 return true; 1786 } 1787 1788 /* 1789 * functionParameterRest 1790 * : parameter ("=" element)? 1791 * ; 1792 */ 1793 private boolean parseFunctionParameterRest() { 1794 boolean noErrors = true; 1795 1796 // Recovery for the case 'fun foo(Array<String>) {}' 1797 if (at(IDENTIFIER) && lookahead(1) == LT) { 1798 error("Parameter name expected"); 1799 parseTypeRef(); 1800 noErrors = false; 1801 } 1802 else { 1803 expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); 1804 1805 if (at(COLON)) { 1806 advance(); // COLON 1807 parseTypeRef(); 1808 } 1809 else { 1810 errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET); 1811 noErrors = false; 1812 } 1813 } 1814 1815 if (at(EQ)) { 1816 advance(); // EQ 1817 myExpressionParsing.parseExpression(); 1818 } 1819 1820 return noErrors; 1821 } 1822 1823 @Override 1824 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) { 1825 return createForTopLevel(builder); 1826 } 1827 1828 /*package*/ static class TokenDetector implements Consumer<IElementType> { 1829 1830 private boolean detected = false; 1831 private final TokenSet tokens; 1832 1833 public TokenDetector(JetKeywordToken token) { 1834 this.tokens = TokenSet.create(token); 1835 } 1836 1837 @Override 1838 public void consume(IElementType item) { 1839 if (tokens.contains(item)) { 1840 detected = true; 1841 } 1842 } 1843 1844 public boolean isDetected() { 1845 return detected; 1846 } 1847 } 1848 }