001 /* 002 * Copyright 2010-2015 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.kotlin.parsing; 018 019 import com.intellij.lang.PsiBuilder; 020 import com.intellij.openapi.diagnostic.Logger; 021 import com.intellij.psi.tree.IElementType; 022 import com.intellij.psi.tree.TokenSet; 023 import org.jetbrains.annotations.NotNull; 024 import org.jetbrains.annotations.Nullable; 025 import org.jetbrains.kotlin.JetNodeType; 026 import org.jetbrains.kotlin.lexer.JetKeywordToken; 027 import org.jetbrains.kotlin.lexer.JetTokens; 028 029 import java.util.HashMap; 030 import java.util.Map; 031 032 import static org.jetbrains.kotlin.JetNodeTypes.*; 033 import static org.jetbrains.kotlin.lexer.JetTokens.*; 034 import static org.jetbrains.kotlin.parsing.JetParsing.AnnotationParsingMode.*; 035 import static org.jetbrains.kotlin.parsing.JetParsing.DeclarationParsingMode.*; 036 037 public class JetParsing extends AbstractJetParsing { 038 private static final Logger LOG = Logger.getInstance(JetParsing.class); 039 040 // TODO: token sets to constants, including derived methods 041 public static final Map<String, IElementType> MODIFIER_KEYWORD_MAP = new HashMap<String, IElementType>(); 042 static { 043 for (IElementType softKeyword : MODIFIER_KEYWORDS.getTypes()) { 044 MODIFIER_KEYWORD_MAP.put(((JetKeywordToken) softKeyword).getValue(), softKeyword); 045 } 046 } 047 048 private static final TokenSet TOP_LEVEL_DECLARATION_FIRST = TokenSet.create( 049 TYPE_ALIAS_KEYWORD, TRAIT_KEYWORD, INTERFACE_KEYWORD, CLASS_KEYWORD, OBJECT_KEYWORD, 050 FUN_KEYWORD, VAL_KEYWORD, PACKAGE_KEYWORD); 051 private static final TokenSet DECLARATION_FIRST = TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, 052 TokenSet.create(INIT_KEYWORD, GET_KEYWORD, SET_KEYWORD, CONSTRUCTOR_KEYWORD)); 053 054 private static final TokenSet CLASS_NAME_RECOVERY_SET = TokenSet.orSet(TokenSet.create(LT, LPAR, COLON, LBRACE), 055 TOP_LEVEL_DECLARATION_FIRST); 056 private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, LPAR, COLON, LBRACE, GT); 057 private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR); 058 private static final TokenSet PACKAGE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON); 059 private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON); 060 /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, CAPITALIZED_THIS_KEYWORD, HASH, DYNAMIC_KEYWORD); 061 private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); 062 private static final TokenSet VALUE_PARAMETER_FIRST = 063 TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD), MODIFIER_KEYWORDS); 064 private static final TokenSet LAMBDA_VALUE_PARAMETER_FIRST = 065 TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS); 066 private static final TokenSet SOFT_KEYWORDS_AT_MEMBER_START = TokenSet.create(CONSTRUCTOR_KEYWORD, INIT_KEYWORD); 067 private static final TokenSet ANNOTATION_TARGETS = TokenSet.create( 068 FILE_KEYWORD, FIELD_KEYWORD, GET_KEYWORD, SET_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SPARAM_KEYWORD); 069 070 static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) { 071 JetParsing jetParsing = new JetParsing(builder); 072 jetParsing.myExpressionParsing = new JetExpressionParsing(builder, jetParsing); 073 return jetParsing; 074 } 075 076 private static JetParsing createForByClause(SemanticWhitespaceAwarePsiBuilder builder) { 077 final SemanticWhitespaceAwarePsiBuilderForByClause builderForByClause = new SemanticWhitespaceAwarePsiBuilderForByClause(builder); 078 JetParsing jetParsing = new JetParsing(builderForByClause); 079 jetParsing.myExpressionParsing = new JetExpressionParsing(builderForByClause, jetParsing) { 080 @Override 081 protected boolean parseCallWithClosure() { 082 if (builderForByClause.getStackSize() > 0) { 083 return super.parseCallWithClosure(); 084 } 085 return false; 086 } 087 088 @Override 089 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) { 090 return createForByClause(builder); 091 } 092 }; 093 return jetParsing; 094 } 095 096 private JetExpressionParsing myExpressionParsing; 097 098 private JetParsing(SemanticWhitespaceAwarePsiBuilder builder) { 099 super(builder); 100 } 101 102 /* 103 * [start] jetlFile 104 * : preamble toplevelObject* [eof] 105 * ; 106 */ 107 void parseFile() { 108 PsiBuilder.Marker fileMarker = mark(); 109 110 parsePreamble(); 111 112 while (!eof()) { 113 parseTopLevelDeclaration(); 114 } 115 116 fileMarker.done(JET_FILE); 117 } 118 119 void parseTypeCodeFragment() { 120 PsiBuilder.Marker marker = mark(); 121 parseTypeRef(); 122 123 checkForUnexpectedSymbols(); 124 125 marker.done(TYPE_CODE_FRAGMENT); 126 } 127 128 void parseExpressionCodeFragment() { 129 PsiBuilder.Marker marker = mark(); 130 myExpressionParsing.parseExpression(); 131 132 checkForUnexpectedSymbols(); 133 134 marker.done(EXPRESSION_CODE_FRAGMENT); 135 } 136 137 void parseBlockCodeFragment() { 138 PsiBuilder.Marker marker = mark(); 139 PsiBuilder.Marker blockMarker = mark(); 140 141 if (at(PACKAGE_KEYWORD) || at(IMPORT_KEYWORD)) { 142 PsiBuilder.Marker err = mark(); 143 parsePreamble(); 144 err.error("Package directive and imports are forbidden in code fragments"); 145 } 146 147 myExpressionParsing.parseStatements(); 148 149 checkForUnexpectedSymbols(); 150 151 blockMarker.done(BLOCK); 152 marker.done(BLOCK_CODE_FRAGMENT); 153 } 154 155 void parseScript() { 156 PsiBuilder.Marker fileMarker = mark(); 157 158 parsePreamble(); 159 160 PsiBuilder.Marker scriptMarker = mark(); 161 162 PsiBuilder.Marker blockMarker = mark(); 163 164 myExpressionParsing.parseStatements(); 165 166 checkForUnexpectedSymbols(); 167 168 blockMarker.done(BLOCK); 169 scriptMarker.done(SCRIPT); 170 fileMarker.done(JET_FILE); 171 } 172 173 private void checkForUnexpectedSymbols() { 174 while (!eof()) { 175 errorAndAdvance("unexpected symbol"); 176 } 177 } 178 179 /* 180 *preamble 181 * : fileAnnotationList? packageDirective? import* 182 * ; 183 */ 184 private void parsePreamble() { 185 PsiBuilder.Marker firstEntry = mark(); 186 187 /* 188 * fileAnnotationList 189 * : fileAnnotations* 190 */ 191 parseFileAnnotationList(FILE_ANNOTATIONS_BEFORE_PACKAGE); 192 193 /* 194 * packageDirective 195 * : modifiers "package" SimpleName{"."} SEMI? 196 * ; 197 */ 198 PsiBuilder.Marker packageDirective = mark(); 199 parseModifierList(ALLOW_UNESCAPED_REGULAR_ANNOTATIONS); 200 201 if (at(PACKAGE_KEYWORD)) { 202 advance(); // PACKAGE_KEYWORD 203 204 parsePackageName(); 205 206 firstEntry.drop(); 207 208 consumeIf(SEMICOLON); 209 210 packageDirective.done(PACKAGE_DIRECTIVE); 211 } 212 else { 213 // When package directive is omitted we should not report error on non-file annotations at the beginning of the file. 214 // So, we rollback the parsing position and reparse file annotation list without report error on non-file annotations. 215 firstEntry.rollbackTo(); 216 217 parseFileAnnotationList(FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED); 218 packageDirective = mark(); 219 packageDirective.done(PACKAGE_DIRECTIVE); 220 // this is necessary to allow comments at the start of the file to be bound to the first declaration 221 packageDirective.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null); 222 } 223 224 parseImportDirectives(); 225 } 226 227 /* SimpleName{"."} */ 228 private void parsePackageName() { 229 PsiBuilder.Marker qualifiedExpression = mark(); 230 boolean simpleName = true; 231 while (true) { 232 if (myBuilder.newlineBeforeCurrentToken()) { 233 errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", PACKAGE_NAME_RECOVERY_SET); 234 break; 235 } 236 237 if (at(DOT)) { 238 advance(); // DOT 239 qualifiedExpression.error("Package name must be a '.'-separated identifier list"); 240 qualifiedExpression = mark(); 241 continue; 242 } 243 244 PsiBuilder.Marker nsName = mark(); 245 boolean simpleNameFound = expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", PACKAGE_NAME_RECOVERY_SET); 246 if (simpleNameFound) { 247 nsName.done(REFERENCE_EXPRESSION); 248 } 249 else { 250 nsName.drop(); 251 } 252 253 if (!simpleName) { 254 PsiBuilder.Marker precedingMarker = qualifiedExpression.precede(); 255 qualifiedExpression.done(DOT_QUALIFIED_EXPRESSION); 256 qualifiedExpression = precedingMarker; 257 } 258 259 if (at(DOT)) { 260 advance(); // DOT 261 262 if (simpleName && !simpleNameFound) { 263 qualifiedExpression.drop(); 264 qualifiedExpression = mark(); 265 } 266 else { 267 simpleName = false; 268 } 269 } 270 else { 271 break; 272 } 273 } 274 qualifiedExpression.drop(); 275 } 276 277 /* 278 * import 279 * : "import" SimpleName{"."} ("." "*" | "as" SimpleName)? SEMI? 280 * ; 281 */ 282 private void parseImportDirective() { 283 assert _at(IMPORT_KEYWORD); 284 PsiBuilder.Marker importDirective = mark(); 285 advance(); // IMPORT_KEYWORD 286 287 if (closeImportWithErrorIfNewline(importDirective, "Expecting qualified name")) { 288 return; 289 } 290 291 if (!at(IDENTIFIER)) { 292 PsiBuilder.Marker error = mark(); 293 skipUntil(TokenSet.create(EOL_OR_SEMICOLON)); 294 error.error("Expecting qualified name"); 295 importDirective.done(IMPORT_DIRECTIVE); 296 consumeIf(SEMICOLON); 297 return; 298 } 299 300 PsiBuilder.Marker qualifiedName = mark(); 301 PsiBuilder.Marker reference = mark(); 302 advance(); // IDENTIFIER 303 reference.done(REFERENCE_EXPRESSION); 304 305 while (at(DOT) && lookahead(1) != MUL) { 306 advance(); // DOT 307 308 if (closeImportWithErrorIfNewline(importDirective, "Import must be placed on a single line")) { 309 qualifiedName.drop(); 310 return; 311 } 312 313 reference = mark(); 314 if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", IMPORT_RECOVERY_SET)) { 315 reference.done(REFERENCE_EXPRESSION); 316 } 317 else { 318 reference.drop(); 319 } 320 321 PsiBuilder.Marker precede = qualifiedName.precede(); 322 qualifiedName.done(DOT_QUALIFIED_EXPRESSION); 323 qualifiedName = precede; 324 } 325 qualifiedName.drop(); 326 327 if (at(DOT)) { 328 advance(); // DOT 329 assert _at(MUL); 330 advance(); // MUL 331 if (at(AS_KEYWORD)) { 332 PsiBuilder.Marker as = mark(); 333 advance(); // AS_KEYWORD 334 if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) { 335 as.drop(); 336 return; 337 } 338 consumeIf(IDENTIFIER); 339 as.error("Cannot rename all imported items to one identifier"); 340 } 341 } 342 if (at(AS_KEYWORD)) { 343 advance(); // AS_KEYWORD 344 if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) { 345 return; 346 } 347 expect(IDENTIFIER, "Expecting identifier", TokenSet.create(SEMICOLON)); 348 } 349 consumeIf(SEMICOLON); 350 importDirective.done(IMPORT_DIRECTIVE); 351 importDirective.setCustomEdgeTokenBinders(null, TrailingCommentsBinder.INSTANCE$); 352 } 353 354 private boolean closeImportWithErrorIfNewline(PsiBuilder.Marker importDirective, String errorMessage) { 355 if (myBuilder.newlineBeforeCurrentToken()) { 356 error(errorMessage); 357 importDirective.done(IMPORT_DIRECTIVE); 358 return true; 359 } 360 return false; 361 } 362 363 private void parseImportDirectives() { 364 PsiBuilder.Marker importList = mark(); 365 if (!at(IMPORT_KEYWORD)) { 366 // this is necessary to allow comments at the start of the file to be bound to the first declaration 367 importList.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null); 368 } 369 while (at(IMPORT_KEYWORD)) { 370 parseImportDirective(); 371 } 372 importList.done(IMPORT_LIST); 373 } 374 375 /* 376 * toplevelObject 377 * : package 378 * : class 379 * : extension 380 * : function 381 * : property 382 * : typeAlias 383 * : object 384 * ; 385 */ 386 private void parseTopLevelDeclaration() { 387 if (at(SEMICOLON)) { 388 advance(); // SEMICOLON 389 return; 390 } 391 PsiBuilder.Marker decl = mark(); 392 393 ModifierDetector detector = new ModifierDetector(); 394 parseModifierList(detector, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS); 395 396 IElementType keywordToken = tt(); 397 IElementType declType = null; 398 // if (keywordToken == PACKAGE_KEYWORD) { 399 // declType = parsePackageBlock(); 400 // } 401 // else 402 if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD || keywordToken == INTERFACE_KEYWORD) { 403 declType = parseClass(detector.isEnumDetected(), TOP_LEVEL); 404 } 405 else if (keywordToken == FUN_KEYWORD) { 406 declType = parseFunction(); 407 } 408 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { 409 declType = parseProperty(); 410 } 411 else if (keywordToken == TYPE_ALIAS_KEYWORD) { 412 declType = parseTypeAlias(); 413 } 414 else if (keywordToken == OBJECT_KEYWORD) { 415 parseObject(NameParsingMode.REQUIRED, true, TOP_LEVEL); 416 declType = OBJECT_DECLARATION; 417 } 418 else if (at(LBRACE)) { 419 error("Expecting a top level declaration"); 420 parseBlock(); 421 declType = FUN; 422 } 423 424 if (declType == null) { 425 errorAndAdvance("Expecting a top level declaration"); 426 decl.drop(); 427 } 428 else { 429 closeDeclarationWithCommentBinders(decl, declType, true); 430 } 431 } 432 433 /* 434 * (modifier | annotation)* 435 */ 436 boolean parseModifierList( 437 @NotNull AnnotationParsingMode annotationParsingMode 438 ) { 439 return parseModifierList(null, annotationParsingMode); 440 } 441 442 /** 443 * (modifier | annotation)* 444 * 445 * Feeds modifiers (not annotations) into the passed consumer, if it is not null 446 */ 447 boolean parseModifierList( 448 @Nullable Consumer<IElementType> tokenConsumer, 449 @NotNull AnnotationParsingMode annotationParsingMode 450 ) { 451 PsiBuilder.Marker list = mark(); 452 boolean empty = true; 453 while (!eof()) { 454 if (annotationParsingMode.atMemberStart && atSet(SOFT_KEYWORDS_AT_MEMBER_START)) break; 455 if ((annotationParsingMode == PRIMARY_CONSTRUCTOR_MODIFIER_LIST || annotationParsingMode == PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL) && 456 atSet(CONSTRUCTOR_KEYWORD, WHERE_KEYWORD)) break; 457 458 if (at(AT)) { 459 if (!tryParseModifier(tokenConsumer)) { 460 parseAnnotationOrList(annotationParsingMode); 461 } 462 } 463 else if (tryParseModifier(tokenConsumer)) { 464 // modifier advanced 465 } 466 else if (annotationParsingMode.allowShortAnnotations && at(IDENTIFIER)) { 467 parseAnnotation(annotationParsingMode); 468 } 469 else { 470 break; 471 } 472 empty = false; 473 } 474 if (empty) { 475 list.drop(); 476 } 477 else { 478 list.done(MODIFIER_LIST); 479 } 480 return !empty; 481 } 482 483 private boolean tryParseModifier(@Nullable Consumer<IElementType> tokenConsumer) { 484 PsiBuilder.Marker marker = mark(); 485 486 if (at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(1))) { 487 advance(); // AT 488 if (atSet(ANNOTATION_MODIFIERS_KEYWORDS)) { 489 myBuilder.remapCurrentToken(IDENTIFIER); 490 marker.rollbackTo(); 491 return false; 492 } 493 } 494 495 if (atSet(MODIFIER_KEYWORDS)) { 496 IElementType tt = tt(); 497 if (tokenConsumer != null) { 498 tokenConsumer.consume(tt); 499 } 500 advance(); // MODIFIER 501 marker.collapse(tt); 502 return true; 503 } 504 505 marker.rollbackTo(); 506 return false; 507 } 508 509 /* 510 * fileAnnotationList 511 * : ("[" "file:" annotationEntry+ "]")* 512 * ; 513 */ 514 private void parseFileAnnotationList(AnnotationParsingMode mode) { 515 if (!mode.isFileAnnotationParsingMode) { 516 LOG.error("expected file annotation parsing mode, but:" + mode); 517 } 518 519 PsiBuilder.Marker fileAnnotationsList = mark(); 520 521 if (parseAnnotations(mode)) { 522 fileAnnotationsList.done(FILE_ANNOTATION_LIST); 523 } 524 else { 525 fileAnnotationsList.drop(); 526 } 527 } 528 529 /* 530 * annotations 531 * : (annotation | annotationList)* 532 * ; 533 */ 534 boolean parseAnnotations(AnnotationParsingMode mode) { 535 if (!parseAnnotationOrList(mode)) return false; 536 537 while (parseAnnotationOrList(mode)) { 538 // do nothing 539 } 540 541 return true; 542 } 543 544 /* 545 * annotation 546 * : annotationPrefix? unescapedAnnotation 547 * ; 548 * 549 * annotationList 550 * : annotationPrefix "[" unescapedAnnotation+ "]" 551 * ; 552 * 553 * annotationUseSiteTarget 554 * : "file" 555 * : "field" 556 * : "property" 557 * : "get" 558 * : "set" 559 * : "param" 560 * : "sparam" 561 * ; 562 * 563 * annotationPrefix: 564 * : ("@" (annotationUseSiteTarget ":")?) 565 * ; 566 */ 567 private boolean parseAnnotationOrList(AnnotationParsingMode mode) { 568 if (mode.allowShortAnnotations && at(IDENTIFIER)) { 569 return parseAnnotation(mode); 570 } 571 else if (at(AT)) { 572 IElementType nextRawToken = myBuilder.rawLookup(1); 573 IElementType tokenToMatch = nextRawToken; 574 boolean isTargetedAnnotation = false; 575 576 if ((nextRawToken == IDENTIFIER || ANNOTATION_TARGETS.contains(nextRawToken)) && lookahead(2) == COLON) { 577 tokenToMatch = lookahead(3); 578 isTargetedAnnotation = true; 579 } 580 else if (lookahead(1) == COLON) { 581 // recovery for "@:ann" 582 isTargetedAnnotation = true; 583 tokenToMatch = lookahead(2); 584 } 585 586 if (tokenToMatch == IDENTIFIER) { 587 return parseAnnotation(mode); 588 } 589 else if (tokenToMatch == LBRACKET) { 590 return parseAnnotationList(mode); 591 } 592 else { 593 if (isTargetedAnnotation) { 594 if (lookahead(1) == COLON) { 595 errorAndAdvance("Expected annotation identifier after ':'", 2); // AT, COLON 596 } 597 else { 598 errorAndAdvance("Expected annotation identifier after ':'", 3); // AT, (ANNOTATION TARGET KEYWORD), COLON 599 } 600 } 601 else { 602 errorAndAdvance("Expected annotation identifier after '@'", 1); // AT 603 } 604 } 605 return true; 606 } 607 608 return false; 609 } 610 611 private boolean parseAnnotationList(AnnotationParsingMode mode) { 612 assert _at(AT); 613 PsiBuilder.Marker annotation = mark(); 614 615 myBuilder.disableNewlines(); 616 617 advance(); // AT 618 619 if (!parseAnnotationTargetIfNeeded(mode)) { 620 annotation.rollbackTo(); 621 myBuilder.restoreNewlinesState(); 622 return false; 623 } 624 625 assert _at(LBRACKET); 626 advance(); // LBRACKET 627 628 if (!at(IDENTIFIER) && !at(AT)) { 629 error("Expecting a list of annotations"); 630 } 631 else { 632 while (at(IDENTIFIER) || at(AT)) { 633 if (at(AT)) { 634 errorAndAdvance("No '@' needed in annotation list"); // AT 635 continue; 636 } 637 638 parseAnnotation(ALLOW_UNESCAPED_REGULAR_ANNOTATIONS); 639 while (at(COMMA)) { 640 errorAndAdvance("No commas needed to separate annotations"); 641 } 642 } 643 } 644 645 expect(RBRACKET, "Expecting ']' to close the annotation list"); 646 myBuilder.restoreNewlinesState(); 647 648 annotation.done(ANNOTATION); 649 return true; 650 } 651 652 // Returns true if we should continue parse annotation 653 private boolean parseAnnotationTargetIfNeeded(AnnotationParsingMode mode) { 654 String expectedAnnotationTargetBeforeColon = "Expected annotation target before ':'"; 655 656 if (at(COLON)) { 657 // recovery for "@:ann" 658 errorAndAdvance(expectedAnnotationTargetBeforeColon); // COLON 659 return true; 660 } 661 662 JetKeywordToken targetKeyword = atTargetKeyword(); 663 if (mode == FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED && !(targetKeyword == FILE_KEYWORD && lookahead(1) == COLON)) { 664 return false; 665 } 666 667 if (lookahead(1) == COLON && targetKeyword == null && at(IDENTIFIER)) { 668 // recovery for "@fil:ann" 669 errorAndAdvance(expectedAnnotationTargetBeforeColon); // IDENTIFIER 670 advance(); // COLON 671 return true; 672 } 673 674 if (targetKeyword == null && mode.isFileAnnotationParsingMode) { 675 parseAnnotationTarget(mode, FILE_KEYWORD); 676 } 677 else if (targetKeyword != null) { 678 parseAnnotationTarget(mode, targetKeyword); 679 } 680 681 return true; 682 } 683 684 private void parseAnnotationTarget(AnnotationParsingMode mode, JetKeywordToken keyword) { 685 if (keyword == FILE_KEYWORD && !mode.isFileAnnotationParsingMode && at(keyword) && lookahead(1) == COLON) { 686 errorAndAdvance(AT.getValue() + keyword.getValue() + " annotations are only allowed before package declaration", 2); 687 return; 688 } 689 690 String message = "Expecting \"" + keyword.getValue() + COLON.getValue() + "\" prefix for " + keyword.getValue() + " annotations"; 691 692 PsiBuilder.Marker marker = mark(); 693 694 if (!expect(keyword, message)) { 695 marker.drop(); 696 } 697 else { 698 marker.done(ANNOTATION_TARGET); 699 } 700 701 expect(COLON, message, TokenSet.create(IDENTIFIER, RBRACKET, LBRACKET)); 702 } 703 704 @Nullable 705 private JetKeywordToken atTargetKeyword() { 706 for (IElementType target : ANNOTATION_TARGETS.getTypes()) { 707 if (at(target)) return (JetKeywordToken) target; 708 } 709 return null; 710 } 711 712 /* 713 * annotation 714 * : annotationPrefix? unescapedAnnotation 715 * ; 716 * 717 * unescapedAnnotation 718 * : SimpleName{"."} typeArguments? valueArguments? 719 * ; 720 */ 721 private boolean parseAnnotation(AnnotationParsingMode mode) { 722 assert _at(IDENTIFIER) || 723 (_at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(1))); 724 725 PsiBuilder.Marker annotation = mark(); 726 727 boolean atAt = at(AT); 728 if (atAt) { 729 advance(); // AT 730 } 731 732 if (atAt && !parseAnnotationTargetIfNeeded(mode)) { 733 annotation.rollbackTo(); 734 return false; 735 } 736 737 PsiBuilder.Marker reference = mark(); 738 PsiBuilder.Marker typeReference = mark(); 739 parseUserType(); 740 typeReference.done(TYPE_REFERENCE); 741 reference.done(CONSTRUCTOR_CALLEE); 742 743 parseTypeArgumentList(); 744 745 if (at(LPAR)) { 746 myExpressionParsing.parseValueArgumentList(); 747 } 748 annotation.done(ANNOTATION_ENTRY); 749 750 return true; 751 } 752 753 public enum NameParsingMode { 754 REQUIRED, 755 ALLOWED, 756 PROHIBITED 757 } 758 759 public enum DeclarationParsingMode { 760 TOP_LEVEL, 761 CLASS_MEMBER, 762 LOCAL 763 } 764 765 /* 766 * class 767 * : modifiers ("class" | "interface") SimpleName 768 * typeParameters? 769 * primaryConstructor? 770 * (":" annotations delegationSpecifier{","})? 771 * typeConstraints 772 * (classBody? | enumClassBody) 773 * ; 774 * 775 * primaryConstructor 776 * : (modifiers "constructor")? ("(" functionParameter{","} ")") 777 * ; 778 * 779 * object 780 * : "object" SimpleName? primaryConstructor? ":" delegationSpecifier{","}? classBody? 781 * ; 782 */ 783 IElementType parseClassOrObject( 784 boolean object, 785 NameParsingMode nameParsingMode, 786 boolean optionalBody, 787 boolean enumClass, 788 DeclarationParsingMode declarationParsingMode 789 ) { 790 if (object) { 791 assert _at(OBJECT_KEYWORD); 792 } 793 else { 794 assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD, INTERFACE_KEYWORD); 795 } 796 advance(); // CLASS_KEYWORD, TRAIT_KEYWORD or OBJECT_KEYWORD 797 798 if (nameParsingMode == NameParsingMode.REQUIRED) { 799 OptionalMarker marker = new OptionalMarker(object); 800 expect(IDENTIFIER, "Name expected", CLASS_NAME_RECOVERY_SET); 801 marker.done(OBJECT_DECLARATION_NAME); 802 } 803 else { 804 assert object : "Must be an object to be nameless"; 805 if (at(IDENTIFIER)) { 806 if (nameParsingMode == NameParsingMode.PROHIBITED) { 807 errorAndAdvance("An object expression cannot bind a name"); 808 } 809 else { 810 assert nameParsingMode == NameParsingMode.ALLOWED; 811 PsiBuilder.Marker marker = mark(); 812 advance(); 813 marker.done(OBJECT_DECLARATION_NAME); 814 } 815 } 816 } 817 818 OptionalMarker typeParamsMarker = new OptionalMarker(object); 819 boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET); 820 typeParamsMarker.error("Type parameters are not allowed for objects"); 821 822 PsiBuilder.Marker beforeConstructorModifiers = mark(); 823 PsiBuilder.Marker primaryConstructorMarker = mark(); 824 boolean hasConstructorModifiers = parseModifierList( 825 declarationParsingMode != LOCAL ? PRIMARY_CONSTRUCTOR_MODIFIER_LIST : PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL 826 ); 827 828 // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else 829 if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD)) { 830 beforeConstructorModifiers.rollbackTo(); 831 return object ? OBJECT_DECLARATION : CLASS; 832 } 833 834 // We are still inside a class declaration 835 beforeConstructorModifiers.drop(); 836 837 boolean hasConstructorKeyword = at(CONSTRUCTOR_KEYWORD); 838 if (hasConstructorKeyword) { 839 advance(); // CONSTRUCTOR_KEYWORD 840 } 841 842 if (at(LPAR)) { 843 parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(LBRACE, RBRACE)); 844 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR); 845 } 846 else if (hasConstructorModifiers || hasConstructorKeyword) { 847 // A comprehensive error message for cases like: 848 // class A private : Foo 849 // or 850 // class A private { 851 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR); 852 if (hasConstructorKeyword) { 853 error("Expecting primary constructor parameter list"); 854 } 855 else { 856 error("Expecting 'constructor' keyword"); 857 } 858 } 859 else { 860 primaryConstructorMarker.drop(); 861 } 862 863 if (at(COLON)) { 864 advance(); // COLON 865 parseDelegationSpecifierList(); 866 } 867 868 OptionalMarker whereMarker = new OptionalMarker(object); 869 parseTypeConstraintsGuarded(typeParametersDeclared); 870 whereMarker.error("Where clause is not allowed for objects"); 871 872 if (at(LBRACE)) { 873 if (enumClass) { 874 parseEnumClassBody(); 875 } 876 else { 877 parseClassBody(); 878 } 879 } 880 else if (!optionalBody) { 881 PsiBuilder.Marker fakeBody = mark(); 882 error("Expecting a class body"); 883 fakeBody.done(CLASS_BODY); 884 } 885 886 return object ? OBJECT_DECLARATION : CLASS; 887 } 888 889 IElementType parseClass(boolean enumClass, DeclarationParsingMode declarationParsingMode) { 890 return parseClassOrObject(false, NameParsingMode.REQUIRED, true, enumClass, declarationParsingMode); 891 } 892 893 void parseObject(NameParsingMode nameParsingMode, boolean optionalBody, DeclarationParsingMode declarationParsingMode) { 894 parseClassOrObject(true, nameParsingMode, optionalBody, false, declarationParsingMode); 895 } 896 897 /* 898 * enumClassBody 899 * : "{" enumEntries (";" members)? "}" 900 * ; 901 */ 902 private void parseEnumClassBody() { 903 if (!at(LBRACE)) return; 904 905 PsiBuilder.Marker body = mark(); 906 myBuilder.enableNewlines(); 907 908 advance(); // LBRACE 909 910 if (!parseEnumEntries() && !at(RBRACE)) { 911 error("Expecting ';' after the last enum entry or '}' to close enum class body"); 912 } 913 parseMembers(); 914 expect(RBRACE, "Expecting '}' to close enum class body"); 915 916 myBuilder.restoreNewlinesState(); 917 body.done(CLASS_BODY); 918 } 919 920 /** 921 * enumEntries 922 * : enumEntry{","}? 923 * ; 924 * 925 * @return true if enum regular members can follow, false otherwise 926 */ 927 private boolean parseEnumEntries() { 928 while (!eof() && !at(RBRACE)) { 929 switch (parseEnumEntry()) { 930 case FAILED: 931 // Special case without any enum entries but with possible members after semicolon 932 if (at(SEMICOLON)) { 933 advance(); 934 return true; 935 } 936 else { 937 return false; 938 } 939 case NO_DELIMITER: 940 return false; 941 case COMMA_DELIMITER: 942 break; 943 case SEMICOLON_DELIMITER: 944 return true; 945 } 946 } 947 return false; 948 } 949 950 private enum ParseEnumEntryResult { 951 FAILED, 952 NO_DELIMITER, 953 COMMA_DELIMITER, 954 SEMICOLON_DELIMITER 955 } 956 957 /* 958 * enumEntry 959 * : modifiers SimpleName ("(" arguments ")")? classBody? 960 * ; 961 */ 962 private ParseEnumEntryResult parseEnumEntry() { 963 PsiBuilder.Marker entry = mark(); 964 965 parseModifierListWithStopAt(TokenSet.create(COMMA, SEMICOLON, RBRACE), ONLY_ESCAPED_REGULAR_ANNOTATIONS); 966 967 if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) { 968 PsiBuilder.Marker nameAsDeclaration = mark(); 969 advance(); // IDENTIFIER 970 nameAsDeclaration.done(OBJECT_DECLARATION_NAME); 971 972 if (at(LPAR)) { 973 // Arguments should be parsed here 974 // Also, "fake" constructor call tree is created, 975 // with empty type name inside 976 PsiBuilder.Marker initializerList = mark(); 977 PsiBuilder.Marker delegatorSuperCall = mark(); 978 979 PsiBuilder.Marker callee = mark(); 980 PsiBuilder.Marker typeReference = mark(); 981 PsiBuilder.Marker type = mark(); 982 PsiBuilder.Marker referenceExpr = mark(); 983 referenceExpr.done(ENUM_ENTRY_SUPERCLASS_REFERENCE_EXPRESSION); 984 type.done(USER_TYPE); 985 typeReference.done(TYPE_REFERENCE); 986 callee.done(CONSTRUCTOR_CALLEE); 987 988 myExpressionParsing.parseValueArgumentList(); 989 delegatorSuperCall.done(DELEGATOR_SUPER_CALL); 990 initializerList.done(INITIALIZER_LIST); 991 } 992 if (at(LBRACE)) { 993 parseClassBody(); 994 } 995 boolean commaFound = at(COMMA); 996 if (commaFound) { 997 advance(); 998 } 999 boolean semicolonFound = at(SEMICOLON); 1000 if (semicolonFound) { 1001 advance(); 1002 } 1003 1004 // Probably some helper function 1005 closeDeclarationWithCommentBinders(entry, ENUM_ENTRY, true); 1006 return semicolonFound 1007 ? ParseEnumEntryResult.SEMICOLON_DELIMITER 1008 : (commaFound ? ParseEnumEntryResult.COMMA_DELIMITER : ParseEnumEntryResult.NO_DELIMITER); 1009 } 1010 else { 1011 entry.rollbackTo(); 1012 return ParseEnumEntryResult.FAILED; 1013 } 1014 } 1015 1016 /* 1017 * classBody 1018 * : ("{" members "}")? 1019 * ; 1020 */ 1021 private void parseClassBody() { 1022 PsiBuilder.Marker body = mark(); 1023 1024 myBuilder.enableNewlines(); 1025 1026 if (expect(LBRACE, "Expecting a class body")) { 1027 parseMembers(); 1028 expect(RBRACE, "Missing '}"); 1029 } 1030 1031 myBuilder.restoreNewlinesState(); 1032 1033 body.done(CLASS_BODY); 1034 } 1035 1036 /** 1037 * members 1038 * : memberDeclaration* 1039 * ; 1040 */ 1041 private void parseMembers() { 1042 while (!eof() && !at(RBRACE)) { 1043 parseMemberDeclaration(); 1044 } 1045 } 1046 1047 /* 1048 * memberDeclaration 1049 * : modifiers memberDeclaration' 1050 * ; 1051 * 1052 * memberDeclaration' 1053 * : companionObject 1054 * : secondaryConstructor 1055 * : function 1056 * : property 1057 * : class 1058 * : extension 1059 * : typeAlias 1060 * : anonymousInitializer 1061 * : object 1062 * ; 1063 */ 1064 private void parseMemberDeclaration() { 1065 if (at(SEMICOLON)) { 1066 advance(); // SEMICOLON 1067 return; 1068 } 1069 PsiBuilder.Marker decl = mark(); 1070 1071 ModifierDetector detector = new ModifierDetector(); 1072 parseModifierList(detector, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS_AT_MEMBER_MODIFIER_LIST); 1073 1074 IElementType declType = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected()); 1075 1076 if (declType == null) { 1077 errorWithRecovery("Expecting member declaration", TokenSet.EMPTY); 1078 decl.drop(); 1079 } 1080 else { 1081 closeDeclarationWithCommentBinders(decl, declType, true); 1082 } 1083 } 1084 1085 private IElementType parseMemberDeclarationRest(boolean isEnum, boolean isDefault) { 1086 IElementType keywordToken = tt(); 1087 IElementType declType = null; 1088 if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD || keywordToken == INTERFACE_KEYWORD) { 1089 declType = parseClass(isEnum, CLASS_MEMBER); 1090 } 1091 else if (keywordToken == FUN_KEYWORD) { 1092 declType = parseFunction(); 1093 } 1094 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { 1095 declType = parseProperty(); 1096 } 1097 else if (keywordToken == TYPE_ALIAS_KEYWORD) { 1098 declType = parseTypeAlias(); 1099 } 1100 else if (keywordToken == OBJECT_KEYWORD) { 1101 parseObject(isDefault ? NameParsingMode.ALLOWED : NameParsingMode.REQUIRED, true, CLASS_MEMBER); 1102 declType = OBJECT_DECLARATION; 1103 } 1104 else if (at(INIT_KEYWORD)) { 1105 advance(); // init 1106 if (at(LBRACE)) { 1107 parseBlock(); 1108 } 1109 else { 1110 mark().error("Expecting '{' after 'init'"); 1111 } 1112 declType = ANONYMOUS_INITIALIZER; 1113 } 1114 else if (at(CONSTRUCTOR_KEYWORD)) { 1115 parseSecondaryConstructor(); 1116 declType = SECONDARY_CONSTRUCTOR; 1117 } 1118 else if (at(LBRACE)) { 1119 error("Expecting member declaration"); 1120 parseBlock(); 1121 declType = FUN; 1122 } 1123 return declType; 1124 } 1125 1126 /* 1127 * secondaryConstructor 1128 * : modifiers "constructor" valueParameters (":" constructorDelegationCall)? block 1129 * constructorDelegationCall 1130 * : "this" valueArguments 1131 * : "super" valueArguments 1132 */ 1133 private void parseSecondaryConstructor() { 1134 assert _at(CONSTRUCTOR_KEYWORD); 1135 1136 advance(); // CONSTRUCTOR_KEYWORD 1137 1138 TokenSet valueArgsRecoverySet = TokenSet.create(LBRACE, SEMICOLON, RPAR, EOL_OR_SEMICOLON, RBRACE); 1139 if (at(LPAR)) { 1140 parseValueParameterList(false, /*typeRequired = */ true, valueArgsRecoverySet); 1141 } 1142 else { 1143 errorWithRecovery("Expecting '('", TokenSet.orSet(valueArgsRecoverySet, TokenSet.create(COLON))); 1144 } 1145 1146 if (at(COLON)) { 1147 advance(); // COLON 1148 1149 PsiBuilder.Marker delegationCall = mark(); 1150 1151 if (at(THIS_KEYWORD) || at(SUPER_KEYWORD)) { 1152 parseThisOrSuper(); 1153 myExpressionParsing.parseValueArgumentList(); 1154 } 1155 else { 1156 error("Expecting a 'this' or 'super' constructor call"); 1157 PsiBuilder.Marker beforeWrongDelegationCallee = null; 1158 if (!at(LPAR)) { 1159 beforeWrongDelegationCallee = mark(); 1160 advance(); // wrong delegation callee 1161 } 1162 myExpressionParsing.parseValueArgumentList(); 1163 1164 if (beforeWrongDelegationCallee != null) { 1165 if (at(LBRACE)) { 1166 beforeWrongDelegationCallee.drop(); 1167 } 1168 else { 1169 beforeWrongDelegationCallee.rollbackTo(); 1170 } 1171 } 1172 } 1173 1174 delegationCall.done(CONSTRUCTOR_DELEGATION_CALL); 1175 } 1176 else { 1177 // empty constructor delegation call 1178 PsiBuilder.Marker emptyDelegationCall = mark(); 1179 mark().done(CONSTRUCTOR_DELEGATION_REFERENCE); 1180 emptyDelegationCall.done(CONSTRUCTOR_DELEGATION_CALL); 1181 } 1182 1183 if (at(LBRACE)) { 1184 parseBlock(); 1185 } 1186 } 1187 1188 private void parseThisOrSuper() { 1189 assert _at(THIS_KEYWORD) || _at(SUPER_KEYWORD); 1190 PsiBuilder.Marker mark = mark(); 1191 1192 advance(); // THIS_KEYWORD | SUPER_KEYWORD 1193 1194 mark.done(CONSTRUCTOR_DELEGATION_REFERENCE); 1195 } 1196 1197 /* 1198 * initializer 1199 * : annotations constructorInvocation // type parameters may (must?) be omitted 1200 * ; 1201 */ 1202 private void parseInitializer() { 1203 PsiBuilder.Marker initializer = mark(); 1204 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 1205 1206 IElementType type; 1207 if (atSet(TYPE_REF_FIRST)) { 1208 PsiBuilder.Marker reference = mark(); 1209 parseTypeRef(); 1210 reference.done(CONSTRUCTOR_CALLEE); 1211 type = DELEGATOR_SUPER_CALL; 1212 } 1213 else { 1214 errorWithRecovery("Expecting constructor call (<class-name>(...))", 1215 TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, TokenSet.create(RBRACE, LBRACE, COMMA, SEMICOLON))); 1216 initializer.drop(); 1217 return; 1218 } 1219 myExpressionParsing.parseValueArgumentList(); 1220 1221 initializer.done(type); 1222 } 1223 1224 /* 1225 * typeAlias 1226 * : modifiers "typealias" SimpleName (typeParameters typeConstraints)? "=" type 1227 * ; 1228 */ 1229 JetNodeType parseTypeAlias() { 1230 assert _at(TYPE_ALIAS_KEYWORD); 1231 1232 advance(); // TYPE_ALIAS_KEYWORD 1233 1234 expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOP_LEVEL_DECLARATION_FIRST)); 1235 1236 if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) { 1237 parseTypeConstraints(); 1238 } 1239 1240 expect(EQ, "Expecting '='", TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, TokenSet.create(SEMICOLON))); 1241 1242 parseTypeRef(); 1243 1244 consumeIf(SEMICOLON); 1245 1246 return TYPEDEF; 1247 } 1248 1249 /* 1250 * variableDeclarationEntry 1251 * : SimpleName (":" type)? 1252 * ; 1253 * 1254 * property 1255 * : modifiers ("val" | "var") 1256 * typeParameters? (type "." | annotations)? 1257 * ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry) 1258 * typeConstraints 1259 * ("by" | "=" expression SEMI?)? 1260 * (getter? setter? | setter? getter?) SEMI? 1261 * ; 1262 */ 1263 private IElementType parseProperty() { 1264 return parseProperty(false); 1265 } 1266 1267 public IElementType parseProperty(boolean local) { 1268 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) { 1269 advance(); // VAL_KEYWORD or VAR_KEYWORD 1270 } 1271 else { 1272 errorAndAdvance("Expecting 'val' or 'var'"); 1273 } 1274 1275 boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON)); 1276 1277 TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD); 1278 1279 myBuilder.disableJoiningComplexTokens(); 1280 1281 PsiBuilder.Marker receiver = mark(); 1282 boolean receiverTypeDeclared = parseReceiverType("property", propertyNameFollow); 1283 1284 boolean multiDeclaration = at(LPAR); 1285 1286 errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration"); 1287 1288 if (multiDeclaration) { 1289 PsiBuilder.Marker multiDecl = mark(); 1290 parseMultiDeclarationName(propertyNameFollow); 1291 errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values"); 1292 } 1293 else { 1294 parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow, /*nameRequired = */ false); 1295 } 1296 1297 myBuilder.restoreJoiningComplexTokensState(); 1298 1299 if (at(COLON)) { 1300 PsiBuilder.Marker type = mark(); 1301 advance(); // COLON 1302 parseTypeRef(); 1303 errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations"); 1304 } 1305 1306 parseTypeConstraintsGuarded(typeParametersDeclared); 1307 1308 if (local) { 1309 if (at(BY_KEYWORD)) { 1310 parsePropertyDelegate(); 1311 } 1312 else if (at(EQ)) { 1313 advance(); // EQ 1314 myExpressionParsing.parseExpression(); 1315 // "val a = 1; b" must not be an infix call of b on "val ...;" 1316 } 1317 } 1318 else { 1319 if (at(BY_KEYWORD)) { 1320 parsePropertyDelegate(); 1321 consumeIf(SEMICOLON); 1322 } 1323 else if (at(EQ)) { 1324 advance(); // EQ 1325 myExpressionParsing.parseExpression(); 1326 consumeIf(SEMICOLON); 1327 } 1328 1329 if (parsePropertyGetterOrSetter()) { 1330 parsePropertyGetterOrSetter(); 1331 } 1332 if (!atSet(EOL_OR_SEMICOLON, RBRACE)) { 1333 if (getLastToken() != SEMICOLON) { 1334 errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE)); 1335 } 1336 } 1337 else { 1338 consumeIf(SEMICOLON); 1339 } 1340 } 1341 1342 return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY; 1343 } 1344 1345 /* 1346 * propertyDelegate 1347 * : "by" expression 1348 * ; 1349 */ 1350 private void parsePropertyDelegate() { 1351 assert _at(BY_KEYWORD); 1352 PsiBuilder.Marker delegate = mark(); 1353 advance(); // BY_KEYWORD 1354 myExpressionParsing.parseExpression(); 1355 delegate.done(PROPERTY_DELEGATE); 1356 } 1357 1358 /* 1359 * (SimpleName (":" type)){","} 1360 */ 1361 public void parseMultiDeclarationName(TokenSet follow) { 1362 // Parsing multi-name, e.g. 1363 // val (a, b) = foo() 1364 myBuilder.disableNewlines(); 1365 advance(); // LPAR 1366 1367 TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow); 1368 if (!atSet(follow)) { 1369 while (true) { 1370 if (at(COMMA)) { 1371 errorAndAdvance("Expecting a name"); 1372 } 1373 else if (at(RPAR)) { 1374 error("Expecting a name"); 1375 break; 1376 } 1377 PsiBuilder.Marker property = mark(); 1378 1379 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, RPAR, COLON, IN_KEYWORD, EQ)); 1380 1381 expect(IDENTIFIER, "Expecting a name", recoverySet); 1382 1383 if (at(COLON)) { 1384 advance(); // COLON 1385 parseTypeRef(follow); 1386 } 1387 property.done(MULTI_VARIABLE_DECLARATION_ENTRY); 1388 1389 if (!at(COMMA)) break; 1390 advance(); // COMMA 1391 } 1392 } 1393 1394 expect(RPAR, "Expecting ')'", follow); 1395 myBuilder.restoreNewlinesState(); 1396 } 1397 1398 /* 1399 * getterOrSetter 1400 * : modifiers ("get" | "set") 1401 * : 1402 * ( "get" "(" ")" 1403 * | 1404 * "set" "(" modifiers parameter ")" 1405 * ) functionBody 1406 * ; 1407 */ 1408 private boolean parsePropertyGetterOrSetter() { 1409 PsiBuilder.Marker getterOrSetter = mark(); 1410 1411 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 1412 1413 if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) { 1414 getterOrSetter.rollbackTo(); 1415 return false; 1416 } 1417 1418 boolean setter = at(SET_KEYWORD); 1419 advance(); // GET_KEYWORD or SET_KEYWORD 1420 1421 if (!at(LPAR)) { 1422 // Account for Jet-114 (val a : int get {...}) 1423 TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(AT, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE)); 1424 if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) { 1425 errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ))); 1426 } 1427 else { 1428 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false); 1429 return true; 1430 } 1431 } 1432 1433 myBuilder.disableNewlines(); 1434 expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ)); 1435 if (setter) { 1436 PsiBuilder.Marker parameterList = mark(); 1437 PsiBuilder.Marker setterParameter = mark(); 1438 parseModifierListWithUnescapedAnnotations(TokenSet.create(RPAR, COMMA, COLON)); 1439 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ)); 1440 1441 if (at(COLON)) { 1442 advance(); // COLON 1443 parseTypeRef(); 1444 } 1445 setterParameter.done(VALUE_PARAMETER); 1446 parameterList.done(VALUE_PARAMETER_LIST); 1447 } 1448 if (!at(RPAR)) { 1449 errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, RBRACE, EQ, EOL_OR_SEMICOLON)); 1450 } 1451 if (at(RPAR)) { 1452 advance(); 1453 } 1454 myBuilder.restoreNewlinesState(); 1455 1456 if (at(COLON)) { 1457 advance(); 1458 1459 parseTypeRef(); 1460 } 1461 1462 parseFunctionBody(); 1463 1464 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false); 1465 1466 return true; 1467 } 1468 1469 /* 1470 * function 1471 * : modifiers "fun" typeParameters? 1472 * (type "." | annotations)? 1473 * SimpleName 1474 * typeParameters? functionParameters (":" type)? 1475 * typeConstraints 1476 * functionBody? 1477 * ; 1478 */ 1479 IElementType parseFunction() { 1480 assert _at(FUN_KEYWORD); 1481 1482 advance(); // FUN_KEYWORD 1483 1484 // Recovery for the case of class A { fun| } 1485 if (at(RBRACE)) { 1486 error("Function body expected"); 1487 return FUN; 1488 } 1489 1490 boolean typeParameterListOccurred = false; 1491 if (at(LT)) { 1492 parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, RBRACE, LPAR)); 1493 typeParameterListOccurred = true; 1494 } 1495 1496 myBuilder.disableJoiningComplexTokens(); 1497 1498 TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ); 1499 boolean receiverFound = parseReceiverType("function", functionNameFollow); 1500 1501 // function as expression has no name 1502 parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ true); 1503 1504 myBuilder.restoreJoiningComplexTokensState(); 1505 1506 TokenSet valueParametersFollow = TokenSet.create(EQ, LBRACE, RBRACE, SEMICOLON, RPAR); 1507 1508 if (at(LT)) { 1509 PsiBuilder.Marker error = mark(); 1510 parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow)); 1511 errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function"); 1512 typeParameterListOccurred = true; 1513 } 1514 1515 if (at(LPAR)) { 1516 parseValueParameterList(false, /* typeRequired = */ false, valueParametersFollow); 1517 } 1518 else { 1519 error("Expecting '('"); 1520 } 1521 1522 if (at(COLON)) { 1523 advance(); // COLON 1524 1525 parseTypeRef(); 1526 } 1527 1528 parseTypeConstraintsGuarded(typeParameterListOccurred); 1529 1530 if (at(SEMICOLON)) { 1531 advance(); // SEMICOLON 1532 } 1533 else if (at(EQ) || at(LBRACE)) { 1534 parseFunctionBody(); 1535 } 1536 1537 return FUN; 1538 } 1539 1540 /* 1541 * (type "." | annotations)? 1542 */ 1543 private boolean parseReceiverType(String title, TokenSet nameFollow) { 1544 PsiBuilder.Marker annotations = mark(); 1545 boolean annotationsPresent = parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 1546 int lastDot = lastDotAfterReceiver(); 1547 boolean receiverPresent = lastDot != -1; 1548 if (annotationsPresent) { 1549 if (receiverPresent) { 1550 annotations.rollbackTo(); 1551 } 1552 else { 1553 annotations.error("Annotations are not allowed in this position"); 1554 } 1555 } 1556 else { 1557 annotations.drop(); 1558 } 1559 1560 if (!receiverPresent) return false; 1561 1562 createTruncatedBuilder(lastDot).parseTypeRef(); 1563 1564 if (atSet(RECEIVER_TYPE_TERMINATORS)) { 1565 advance(); // expectation 1566 } 1567 else { 1568 errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow); 1569 } 1570 return true; 1571 } 1572 1573 private int lastDotAfterReceiver() { 1574 if (at(LPAR)) { 1575 return matchTokenStreamPredicate( 1576 new FirstBefore( 1577 new AtSet(RECEIVER_TYPE_TERMINATORS), 1578 new AbstractTokenStreamPredicate() { 1579 @Override 1580 public boolean matching(boolean topLevel) { 1581 if (topLevel && definitelyOutOfReceiver()) { 1582 return true; 1583 } 1584 return topLevel && !at(QUEST) && !at(LPAR) && !at(RPAR); 1585 } 1586 } 1587 )); 1588 } 1589 else { 1590 return matchTokenStreamPredicate( 1591 new LastBefore( 1592 new AtSet(RECEIVER_TYPE_TERMINATORS), 1593 new AbstractTokenStreamPredicate() { 1594 @Override 1595 public boolean matching(boolean topLevel) { 1596 if (topLevel && (definitelyOutOfReceiver() || at(LPAR))) return true; 1597 if (topLevel && at(IDENTIFIER)) { 1598 IElementType lookahead = lookahead(1); 1599 return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST; 1600 } 1601 return false; 1602 } 1603 })); 1604 } 1605 } 1606 1607 private boolean definitelyOutOfReceiver() { 1608 return atSet(EQ, COLON, LBRACE, RBRACE, BY_KEYWORD) || atSet(TOP_LEVEL_DECLARATION_FIRST); 1609 } 1610 1611 /* 1612 * IDENTIFIER 1613 */ 1614 private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) { 1615 if (nameRequired && atSet(nameFollow)) return; // no name 1616 1617 TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE)); 1618 if (!receiverFound) { 1619 expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet); 1620 } 1621 else { 1622 expect(IDENTIFIER, "Expecting " + title + " name", recoverySet); 1623 } 1624 } 1625 1626 /* 1627 * functionBody 1628 * : block 1629 * : "=" element 1630 * ; 1631 */ 1632 private void parseFunctionBody() { 1633 if (at(LBRACE)) { 1634 parseBlock(); 1635 } 1636 else if (at(EQ)) { 1637 advance(); // EQ 1638 myExpressionParsing.parseExpression(); 1639 consumeIf(SEMICOLON); 1640 } 1641 else { 1642 error("Expecting function body"); 1643 } 1644 } 1645 1646 /* 1647 * block 1648 * : "{" (expressions)* "}" 1649 * ; 1650 */ 1651 void parseBlock() { 1652 PsiBuilder.Marker block = mark(); 1653 1654 myBuilder.enableNewlines(); 1655 expect(LBRACE, "Expecting '{' to open a block"); 1656 1657 myExpressionParsing.parseStatements(); 1658 1659 expect(RBRACE, "Expecting '}'"); 1660 myBuilder.restoreNewlinesState(); 1661 1662 block.done(BLOCK); 1663 } 1664 1665 /* 1666 * delegationSpecifier{","} 1667 */ 1668 /*package*/ void parseDelegationSpecifierList() { 1669 PsiBuilder.Marker list = mark(); 1670 1671 while (true) { 1672 if (at(COMMA)) { 1673 errorAndAdvance("Expecting a delegation specifier"); 1674 continue; 1675 } 1676 parseDelegationSpecifier(); 1677 if (!at(COMMA)) break; 1678 advance(); // COMMA 1679 } 1680 1681 list.done(DELEGATION_SPECIFIER_LIST); 1682 } 1683 1684 /* 1685 * delegationSpecifier 1686 * : constructorInvocation // type and constructor arguments 1687 * : userType 1688 * : explicitDelegation 1689 * ; 1690 * 1691 * explicitDelegation 1692 * : userType "by" element 1693 * ; 1694 */ 1695 private void parseDelegationSpecifier() { 1696 PsiBuilder.Marker delegator = mark(); 1697 PsiBuilder.Marker reference = mark(); 1698 parseTypeRef(); 1699 1700 if (at(BY_KEYWORD)) { 1701 reference.drop(); 1702 advance(); // BY_KEYWORD 1703 createForByClause(myBuilder).myExpressionParsing.parseExpression(); 1704 delegator.done(DELEGATOR_BY); 1705 } 1706 else if (at(LPAR)) { 1707 reference.done(CONSTRUCTOR_CALLEE); 1708 myExpressionParsing.parseValueArgumentList(); 1709 delegator.done(DELEGATOR_SUPER_CALL); 1710 } 1711 else { 1712 reference.drop(); 1713 delegator.done(DELEGATOR_SUPER_CLASS); 1714 } 1715 } 1716 1717 /* 1718 * typeParameters 1719 * : ("<" typeParameter{","} ">" 1720 * ; 1721 */ 1722 private boolean parseTypeParameterList(TokenSet recoverySet) { 1723 boolean result = false; 1724 if (at(LT)) { 1725 PsiBuilder.Marker list = mark(); 1726 1727 myBuilder.disableNewlines(); 1728 advance(); // LT 1729 1730 while (true) { 1731 if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration"); 1732 parseTypeParameter(); 1733 1734 if (!at(COMMA)) break; 1735 advance(); // COMMA 1736 } 1737 1738 expect(GT, "Missing '>'", recoverySet); 1739 myBuilder.restoreNewlinesState(); 1740 result = true; 1741 1742 list.done(TYPE_PARAMETER_LIST); 1743 } 1744 return result; 1745 } 1746 1747 /* 1748 * typeConstraints 1749 * : ("where" typeConstraint{","})? 1750 * ; 1751 */ 1752 private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) { 1753 PsiBuilder.Marker error = mark(); 1754 boolean constraints = parseTypeConstraints(); 1755 errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared"); 1756 } 1757 1758 private boolean parseTypeConstraints() { 1759 if (at(WHERE_KEYWORD)) { 1760 parseTypeConstraintList(); 1761 return true; 1762 } 1763 return false; 1764 } 1765 1766 /* 1767 * typeConstraint{","} 1768 */ 1769 private void parseTypeConstraintList() { 1770 assert _at(WHERE_KEYWORD); 1771 1772 advance(); // WHERE_KEYWORD 1773 1774 PsiBuilder.Marker list = mark(); 1775 1776 while (true) { 1777 if (at(COMMA)) errorAndAdvance("Type constraint expected"); 1778 parseTypeConstraint(); 1779 if (!at(COMMA)) break; 1780 advance(); // COMMA 1781 } 1782 1783 list.done(TYPE_CONSTRAINT_LIST); 1784 } 1785 1786 /* 1787 * typeConstraint 1788 * : annotations SimpleName ":" type 1789 * ; 1790 */ 1791 private void parseTypeConstraint() { 1792 PsiBuilder.Marker constraint = mark(); 1793 1794 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 1795 1796 PsiBuilder.Marker reference = mark(); 1797 if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA, LBRACE, RBRACE), TYPE_REF_FIRST))) { 1798 reference.done(REFERENCE_EXPRESSION); 1799 } 1800 else { 1801 reference.drop(); 1802 } 1803 1804 expect(COLON, "Expecting ':' before the upper bound", TokenSet.orSet(TokenSet.create(LBRACE, RBRACE), TYPE_REF_FIRST)); 1805 1806 parseTypeRef(); 1807 1808 constraint.done(TYPE_CONSTRAINT); 1809 } 1810 1811 /* 1812 * typeParameter 1813 * : modifiers SimpleName (":" userType)? 1814 * ; 1815 */ 1816 private void parseTypeParameter() { 1817 if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) { 1818 error("Type parameter declaration expected"); 1819 return; 1820 } 1821 1822 PsiBuilder.Marker mark = mark(); 1823 1824 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, GT, COLON)); 1825 1826 expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY); 1827 1828 if (at(COLON)) { 1829 advance(); // COLON 1830 parseTypeRef(); 1831 } 1832 1833 mark.done(TYPE_PARAMETER); 1834 1835 } 1836 1837 /* 1838 * type 1839 * : annotations typeDescriptor 1840 * 1841 * typeDescriptor 1842 * : selfType 1843 * : functionType 1844 * : userType 1845 * : nullableType 1846 * : "dynamic" 1847 * ; 1848 * 1849 * nullableType 1850 * : typeDescriptor "?" 1851 */ 1852 void parseTypeRef() { 1853 parseTypeRef(TokenSet.EMPTY); 1854 } 1855 1856 void parseTypeRef(TokenSet extraRecoverySet) { 1857 PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet); 1858 typeRefMarker.done(TYPE_REFERENCE); 1859 } 1860 1861 // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop 1862 // on expression-indicating symbols or not 1863 private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) { 1864 PsiBuilder.Marker typeRefMarker = mark(); 1865 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 1866 1867 IElementType lookahead = lookahead(1); 1868 IElementType lookahead2 = lookahead(2); 1869 boolean typeBeforeDot = true; 1870 if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) { 1871 PsiBuilder.Marker dynamicType = mark(); 1872 advance(); // DYNAMIC_KEYWORD 1873 dynamicType.done(DYNAMIC_TYPE); 1874 } 1875 else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) { 1876 parseUserType(); 1877 } 1878 else if (at(LPAR)) { 1879 PsiBuilder.Marker functionOrParenthesizedType = mark(); 1880 1881 // This may be a function parameter list or just a prenthesized type 1882 advance(); // LPAR 1883 parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed 1884 1885 if (at(RPAR)) { 1886 advance(); // RPAR 1887 if (at(ARROW)) { 1888 // It's a function type with one parameter specified 1889 // (A) -> B 1890 functionOrParenthesizedType.rollbackTo(); 1891 parseFunctionType(); 1892 } 1893 else { 1894 // It's a parenthesized type 1895 // (A) 1896 functionOrParenthesizedType.drop(); 1897 } 1898 } 1899 else { 1900 // This must be a function type 1901 // (A, B) -> C 1902 // or 1903 // (a : A) -> C 1904 functionOrParenthesizedType.rollbackTo(); 1905 parseFunctionType(); 1906 } 1907 1908 } 1909 else if (at(CAPITALIZED_THIS_KEYWORD)) { 1910 parseSelfType(); 1911 } 1912 else { 1913 errorWithRecovery("Type expected", 1914 TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, 1915 TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), 1916 extraRecoverySet)); 1917 typeBeforeDot = false; 1918 } 1919 1920 // Disabling token merge is required for cases like 1921 // Int?.(Foo) -> Bar 1922 myBuilder.disableJoiningComplexTokens(); 1923 typeRefMarker = parseNullableTypeSuffix(typeRefMarker); 1924 myBuilder.restoreJoiningComplexTokensState(); 1925 1926 if (typeBeforeDot && at(DOT)) { 1927 // This is a receiver for a function type 1928 // A.(B) -> C 1929 // ^ 1930 1931 PsiBuilder.Marker functionType = typeRefMarker.precede(); 1932 PsiBuilder.Marker receiverType = typeRefMarker.precede(); 1933 typeRefMarker.done(TYPE_REFERENCE); 1934 receiverType.done(FUNCTION_TYPE_RECEIVER); 1935 1936 advance(); // DOT 1937 1938 if (at(LPAR)) { 1939 parseFunctionTypeContents().drop(); 1940 } 1941 else { 1942 error("Expecting function type"); 1943 } 1944 typeRefMarker = functionType.precede(); 1945 1946 functionType.done(FUNCTION_TYPE); 1947 } 1948 1949 return typeRefMarker; 1950 } 1951 1952 @NotNull 1953 PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) { 1954 // ?: is joined regardless of joining state 1955 while (at(QUEST) && myBuilder.rawLookup(1) != COLON) { 1956 PsiBuilder.Marker precede = typeRefMarker.precede(); 1957 advance(); // QUEST 1958 typeRefMarker.done(NULLABLE_TYPE); 1959 typeRefMarker = precede; 1960 } 1961 return typeRefMarker; 1962 } 1963 1964 /* 1965 * userType 1966 * : ("package" ".")? simpleUserType{"."} 1967 * ; 1968 * 1969 * recovers on platform types: 1970 * - Foo! 1971 * - (Mutable)List<Foo>! 1972 * - Array<(out) Foo>! 1973 */ 1974 void parseUserType() { 1975 PsiBuilder.Marker userType = mark(); 1976 1977 if (at(PACKAGE_KEYWORD)) { 1978 advance(); // PACKAGE_KEYWORD 1979 expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER, LBRACE, RBRACE)); 1980 } 1981 1982 PsiBuilder.Marker reference = mark(); 1983 while (true) { 1984 recoverOnParenthesizedWordForPlatformTypes(0, "Mutable", true); 1985 1986 if (expect(IDENTIFIER, "Expecting type name", 1987 TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW, DECLARATION_FIRST))) { 1988 reference.done(REFERENCE_EXPRESSION); 1989 } 1990 else { 1991 reference.drop(); 1992 break; 1993 } 1994 1995 parseTypeArgumentList(); 1996 1997 recoverOnPlatformTypeSuffix(); 1998 1999 if (!at(DOT)) { 2000 break; 2001 } 2002 if (lookahead(1) == LPAR && !atParenthesizedMutableForPlatformTypes(1)) { 2003 // This may be a receiver for a function type 2004 // Int.(Int) -> Int 2005 break; 2006 } 2007 2008 PsiBuilder.Marker precede = userType.precede(); 2009 userType.done(USER_TYPE); 2010 userType = precede; 2011 2012 advance(); // DOT 2013 reference = mark(); 2014 } 2015 2016 userType.done(USER_TYPE); 2017 } 2018 2019 private boolean atParenthesizedMutableForPlatformTypes(int offset) { 2020 return recoverOnParenthesizedWordForPlatformTypes(offset, "Mutable", false); 2021 } 2022 2023 private boolean recoverOnParenthesizedWordForPlatformTypes(int offset, String word, boolean consume) { 2024 // Array<(out) Foo>! or (Mutable)List<Bar>! 2025 if (lookahead(offset) == LPAR && lookahead(offset + 1) == IDENTIFIER && lookahead(offset + 2) == RPAR && lookahead(offset + 3) == IDENTIFIER) { 2026 PsiBuilder.Marker error = mark(); 2027 2028 advance(offset); 2029 2030 advance(); // LPAR 2031 if (!word.equals(myBuilder.getTokenText())) { 2032 // something other than "out" / "Mutable" 2033 error.rollbackTo(); 2034 return false; 2035 } 2036 else { 2037 advance(); // IDENTIFIER('out') 2038 advance(); // RPAR 2039 2040 if (consume) { 2041 error.error("Unexpected tokens"); 2042 } 2043 else { 2044 error.rollbackTo(); 2045 } 2046 2047 return true; 2048 } 2049 } 2050 return false; 2051 } 2052 2053 private void recoverOnPlatformTypeSuffix() { 2054 // Recovery for platform types 2055 if (at(EXCL)) { 2056 PsiBuilder.Marker error = mark(); 2057 advance(); // EXCL 2058 error.error("Unexpected token"); 2059 } 2060 } 2061 2062 /* 2063 * selfType 2064 * : "This" 2065 * ; 2066 */ 2067 private void parseSelfType() { 2068 assert _at(CAPITALIZED_THIS_KEYWORD); 2069 2070 PsiBuilder.Marker type = mark(); 2071 advance(); // CAPITALIZED_THIS_KEYWORD 2072 type.done(SELF_TYPE); 2073 } 2074 2075 /* 2076 * (optionalProjection type){","} 2077 */ 2078 private PsiBuilder.Marker parseTypeArgumentList() { 2079 if (!at(LT)) return null; 2080 2081 PsiBuilder.Marker list = mark(); 2082 2083 tryParseTypeArgumentList(TokenSet.EMPTY); 2084 2085 list.done(TYPE_ARGUMENT_LIST); 2086 return list; 2087 } 2088 2089 boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) { 2090 myBuilder.disableNewlines(); 2091 advance(); // LT 2092 2093 while (true) { 2094 PsiBuilder.Marker projection = mark(); 2095 2096 recoverOnParenthesizedWordForPlatformTypes(0, "out", true); 2097 2098 // TokenSet lookFor = TokenSet.create(IDENTIFIER); 2099 // TokenSet stopAt = TokenSet.create(COMMA, COLON, GT); 2100 // parseModifierListWithUnescapedAnnotations(MODIFIER_LIST, lookFor, stopAt); 2101 // Currently we do not allow annotations 2102 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS); 2103 2104 if (at(MUL)) { 2105 advance(); // MUL 2106 } 2107 else { 2108 parseTypeRef(extraRecoverySet); 2109 } 2110 projection.done(TYPE_PROJECTION); 2111 if (!at(COMMA)) break; 2112 advance(); // COMMA 2113 } 2114 2115 boolean atGT = at(GT); 2116 if (!atGT) { 2117 error("Expecting a '>'"); 2118 } 2119 else { 2120 advance(); // GT 2121 } 2122 myBuilder.restoreNewlinesState(); 2123 return atGT; 2124 } 2125 2126 public void parseModifierListWithUnescapedAnnotations(TokenSet stopAt) { 2127 parseModifierListWithLookForStopAt(TokenSet.create(IDENTIFIER), stopAt, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS); 2128 } 2129 2130 public void parseModifierListWithStopAt(TokenSet stopAt, AnnotationParsingMode mode) { 2131 parseModifierListWithLookForStopAt(TokenSet.create(IDENTIFIER), stopAt, mode); 2132 } 2133 2134 public void parseModifierListWithUnescapedAnnotations(TokenSet lookFor, TokenSet stopAt) { 2135 parseModifierListWithLookForStopAt(lookFor, stopAt, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS); 2136 } 2137 2138 public void parseModifierListWithLookForStopAt(TokenSet lookFor, TokenSet stopAt, AnnotationParsingMode mode) { 2139 int lastId = matchTokenStreamPredicate(new LastBefore(new AtSet(lookFor), new AnnotationTargetStop(stopAt, ANNOTATION_TARGETS), false)); 2140 createTruncatedBuilder(lastId).parseModifierList(mode); 2141 } 2142 2143 private class AnnotationTargetStop extends AbstractTokenStreamPredicate { 2144 private final TokenSet stopAt; 2145 private final TokenSet annotationTargets; 2146 2147 private IElementType previousToken; 2148 private IElementType tokenBeforePrevious; 2149 2150 public AnnotationTargetStop(TokenSet stopAt, TokenSet annotationTargets) { 2151 this.stopAt = stopAt; 2152 this.annotationTargets = annotationTargets; 2153 } 2154 2155 @Override 2156 public boolean matching(boolean topLevel) { 2157 if (atSet(stopAt)) return true; 2158 2159 if (at(COLON) && !(tokenBeforePrevious == AT && (previousToken == IDENTIFIER || annotationTargets.contains(previousToken)))) { 2160 return true; 2161 } 2162 2163 tokenBeforePrevious = previousToken; 2164 previousToken = tt(); 2165 2166 return false; 2167 } 2168 } 2169 2170 /* 2171 * functionType 2172 * : "(" (parameter | modifiers type){","}? ")" "->" type? 2173 * ; 2174 */ 2175 private void parseFunctionType() { 2176 parseFunctionTypeContents().done(FUNCTION_TYPE); 2177 } 2178 2179 private PsiBuilder.Marker parseFunctionTypeContents() { 2180 assert _at(LPAR) : tt(); 2181 PsiBuilder.Marker functionType = mark(); 2182 2183 parseValueParameterList(true, /* typeRequired = */ true, TokenSet.EMPTY); 2184 2185 expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST); 2186 parseTypeRef(); 2187 2188 return functionType; 2189 } 2190 2191 /* 2192 * functionParameters 2193 * : "(" functionParameter{","}? ")" // default values 2194 * ; 2195 * 2196 * functionParameter 2197 * : modifiers functionParameterRest 2198 * ; 2199 * 2200 * functionParameterRest 2201 * : parameter ("=" element)? 2202 * ; 2203 */ 2204 void parseValueParameterList(boolean isFunctionTypeContents, boolean typeRequired, TokenSet recoverySet) { 2205 assert _at(LPAR); 2206 PsiBuilder.Marker parameters = mark(); 2207 2208 myBuilder.disableNewlines(); 2209 advance(); // LPAR 2210 2211 if (!at(RPAR) && !atSet(recoverySet)) { 2212 while (true) { 2213 if (at(COMMA)) { 2214 errorAndAdvance("Expecting a parameter declaration"); 2215 } 2216 else if (at(RPAR)) { 2217 error("Expecting a parameter declaration"); 2218 break; 2219 } 2220 2221 if (isFunctionTypeContents) { 2222 if (!tryParseValueParameter(typeRequired)) { 2223 PsiBuilder.Marker valueParameter = mark(); 2224 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS); // lazy, out, ref 2225 parseTypeRef(); 2226 closeDeclarationWithCommentBinders(valueParameter, VALUE_PARAMETER, false); 2227 } 2228 } 2229 else { 2230 parseValueParameter(typeRequired); 2231 } 2232 2233 if (at(COMMA)) { 2234 advance(); // COMMA 2235 } 2236 else { 2237 if (!at(RPAR)) error("Expecting comma or ')'"); 2238 if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break; 2239 } 2240 } 2241 } 2242 2243 expect(RPAR, "Expecting ')'", recoverySet); 2244 myBuilder.restoreNewlinesState(); 2245 2246 parameters.done(VALUE_PARAMETER_LIST); 2247 } 2248 2249 /* 2250 * functionParameter 2251 * : modifiers ("val" | "var")? parameter ("=" element)? 2252 * ; 2253 */ 2254 private boolean tryParseValueParameter(boolean typeRequired) { 2255 return parseValueParameter(true, typeRequired); 2256 } 2257 2258 public void parseValueParameter(boolean typeRequired) { 2259 parseValueParameter(false, typeRequired); 2260 } 2261 2262 private boolean parseValueParameter(boolean rollbackOnFailure, boolean typeRequired) { 2263 PsiBuilder.Marker parameter = mark(); 2264 2265 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, RPAR)); 2266 2267 if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { 2268 advance(); // VAR_KEYWORD | VAL_KEYWORD 2269 } 2270 2271 if (!parseFunctionParameterRest(typeRequired) && rollbackOnFailure) { 2272 parameter.rollbackTo(); 2273 return false; 2274 } 2275 2276 closeDeclarationWithCommentBinders(parameter, VALUE_PARAMETER, false); 2277 return true; 2278 } 2279 2280 /* 2281 * functionParameterRest 2282 * : parameter ("=" element)? 2283 * ; 2284 */ 2285 private boolean parseFunctionParameterRest(boolean typeRequired) { 2286 boolean noErrors = true; 2287 2288 // Recovery for the case 'fun foo(Array<String>) {}' 2289 // Recovery for the case 'fun foo(: Int) {}' 2290 if ((at(IDENTIFIER) && lookahead(1) == LT) || at(COLON)) { 2291 error("Parameter name expected"); 2292 if (at(COLON)) { 2293 // We keep noErrors == true so that unnamed parameters starting with ":" are not rolled back during parsing of functional types 2294 advance(); // COLON 2295 } 2296 else { 2297 noErrors = false; 2298 } 2299 parseTypeRef(); 2300 } 2301 else { 2302 expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); 2303 2304 if (at(COLON)) { 2305 advance(); // COLON 2306 parseTypeRef(); 2307 } 2308 else if (typeRequired) { 2309 errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET); 2310 noErrors = false; 2311 } 2312 } 2313 2314 if (at(EQ)) { 2315 advance(); // EQ 2316 myExpressionParsing.parseExpression(); 2317 } 2318 2319 return noErrors; 2320 } 2321 2322 @Override 2323 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) { 2324 return createForTopLevel(builder); 2325 } 2326 2327 /*package*/ static class ModifierDetector implements Consumer<IElementType> { 2328 private boolean enumDetected = false; 2329 private boolean defaultDetected = false; 2330 2331 @Override 2332 public void consume(IElementType item) { 2333 if (item == JetTokens.ENUM_KEYWORD) { 2334 enumDetected = true; 2335 } 2336 else if (item == JetTokens.COMPANION_KEYWORD) { 2337 defaultDetected = true; 2338 } 2339 } 2340 2341 public boolean isEnumDetected() { 2342 return enumDetected; 2343 } 2344 2345 public boolean isDefaultDetected() { 2346 return defaultDetected; 2347 } 2348 } 2349 2350 enum AnnotationParsingMode { 2351 FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true, false), 2352 FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true, false), 2353 ONLY_ESCAPED_REGULAR_ANNOTATIONS(false, false, false), 2354 ALLOW_UNESCAPED_REGULAR_ANNOTATIONS(true, false, false), 2355 ALLOW_UNESCAPED_REGULAR_ANNOTATIONS_AT_MEMBER_MODIFIER_LIST(true, false, true), 2356 PRIMARY_CONSTRUCTOR_MODIFIER_LIST(true, false, false), 2357 PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL(false, false, false); 2358 2359 boolean allowShortAnnotations; 2360 boolean isFileAnnotationParsingMode; 2361 boolean atMemberStart; 2362 2363 AnnotationParsingMode( 2364 boolean allowShortAnnotations, 2365 boolean isFileAnnotationParsingMode, 2366 boolean atMemberStart 2367 ) { 2368 this.allowShortAnnotations = allowShortAnnotations; 2369 this.isFileAnnotationParsingMode = isFileAnnotationParsingMode; 2370 this.atMemberStart = atMemberStart; 2371 } 2372 } 2373 }