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.KtNodeType; 026 import org.jetbrains.kotlin.lexer.KtKeywordToken; 027 import org.jetbrains.kotlin.lexer.KtTokens; 028 029 import java.util.HashMap; 030 import java.util.Map; 031 032 import static org.jetbrains.kotlin.KtNodeTypes.*; 033 import static org.jetbrains.kotlin.lexer.KtTokens.*; 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(((KtKeywordToken) softKeyword).getValue(), softKeyword); 045 } 046 } 047 048 private static final TokenSet TOP_LEVEL_DECLARATION_FIRST = TokenSet.create( 049 TYPE_ALIAS_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, SETPARAM_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(DEFAULT, TokenSet.EMPTY); 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, DEFAULT, TokenSet.EMPTY); 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 == 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 @NotNull TokenSet noModifiersBefore 439 ) { 440 return parseModifierList(null, annotationParsingMode, noModifiersBefore); 441 } 442 443 /** 444 * (modifier | annotation)* 445 * 446 * Feeds modifiers (not annotations) into the passed consumer, if it is not null 447 */ 448 boolean parseModifierList( 449 @Nullable Consumer<IElementType> tokenConsumer, 450 @NotNull AnnotationParsingMode annotationParsingMode, 451 @NotNull TokenSet noModifiersBefore 452 ) { 453 PsiBuilder.Marker list = mark(); 454 boolean empty = true; 455 while (!eof()) { 456 if (at(AT) && annotationParsingMode.allowAnnotations) { 457 parseAnnotationOrList(annotationParsingMode); 458 } 459 else if (tryParseModifier(tokenConsumer, noModifiersBefore)) { 460 // modifier advanced 461 } 462 else if (annotationParsingMode.allowShortAnnotations && at(IDENTIFIER)) { 463 error("Use '@' symbol before annotations"); 464 parseAnnotation(annotationParsingMode); 465 } 466 else { 467 break; 468 } 469 empty = false; 470 } 471 if (empty) { 472 list.drop(); 473 } 474 else { 475 list.done(MODIFIER_LIST); 476 } 477 return !empty; 478 } 479 480 private boolean tryParseModifier(@Nullable Consumer<IElementType> tokenConsumer, @NotNull TokenSet noModifiersBefore) { 481 PsiBuilder.Marker marker = mark(); 482 483 if (atSet(MODIFIER_KEYWORDS)) { 484 IElementType lookahead = lookahead(1); 485 if (lookahead != null && !noModifiersBefore.contains(lookahead)) { 486 IElementType tt = tt(); 487 if (tokenConsumer != null) { 488 tokenConsumer.consume(tt); 489 } 490 advance(); // MODIFIER 491 marker.collapse(tt); 492 return true; 493 } 494 } 495 496 marker.rollbackTo(); 497 return false; 498 } 499 500 /* 501 * fileAnnotationList 502 * : ("[" "file:" annotationEntry+ "]")* 503 * ; 504 */ 505 private void parseFileAnnotationList(AnnotationParsingMode mode) { 506 if (!mode.isFileAnnotationParsingMode) { 507 LOG.error("expected file annotation parsing mode, but:" + mode); 508 } 509 510 PsiBuilder.Marker fileAnnotationsList = mark(); 511 512 if (parseAnnotations(mode)) { 513 fileAnnotationsList.done(FILE_ANNOTATION_LIST); 514 } 515 else { 516 fileAnnotationsList.drop(); 517 } 518 } 519 520 /* 521 * annotations 522 * : (annotation | annotationList)* 523 * ; 524 */ 525 boolean parseAnnotations(AnnotationParsingMode mode) { 526 if (!parseAnnotationOrList(mode)) return false; 527 528 while (parseAnnotationOrList(mode)) { 529 // do nothing 530 } 531 532 return true; 533 } 534 535 /* 536 * annotation 537 * : "@" (annotationUseSiteTarget ":")? unescapedAnnotation 538 * ; 539 * 540 * annotationList 541 * : "@" (annotationUseSiteTarget ":")? "[" unescapedAnnotation+ "]" 542 * ; 543 * 544 * annotationUseSiteTarget 545 * : "file" 546 * : "field" 547 * : "property" 548 * : "get" 549 * : "set" 550 * : "param" 551 * : "sparam" 552 * ; 553 */ 554 private boolean parseAnnotationOrList(AnnotationParsingMode mode) { 555 if (at(AT)) { 556 IElementType nextRawToken = myBuilder.rawLookup(1); 557 IElementType tokenToMatch = nextRawToken; 558 boolean isTargetedAnnotation = false; 559 560 if ((nextRawToken == IDENTIFIER || ANNOTATION_TARGETS.contains(nextRawToken)) && lookahead(2) == COLON) { 561 tokenToMatch = lookahead(3); 562 isTargetedAnnotation = true; 563 } 564 else if (lookahead(1) == COLON) { 565 // recovery for "@:ann" 566 isTargetedAnnotation = true; 567 tokenToMatch = lookahead(2); 568 } 569 570 if (tokenToMatch == IDENTIFIER) { 571 return parseAnnotation(mode); 572 } 573 else if (tokenToMatch == LBRACKET) { 574 return parseAnnotationList(mode); 575 } 576 else { 577 if (isTargetedAnnotation) { 578 if (lookahead(1) == COLON) { 579 errorAndAdvance("Expected annotation identifier after ':'", 2); // AT, COLON 580 } 581 else { 582 errorAndAdvance("Expected annotation identifier after ':'", 3); // AT, (ANNOTATION TARGET KEYWORD), COLON 583 } 584 } 585 else { 586 errorAndAdvance("Expected annotation identifier after '@'", 1); // AT 587 } 588 } 589 return true; 590 } 591 592 return false; 593 } 594 595 private boolean parseAnnotationList(AnnotationParsingMode mode) { 596 assert _at(AT); 597 PsiBuilder.Marker annotation = mark(); 598 599 myBuilder.disableNewlines(); 600 601 advance(); // AT 602 603 if (!parseAnnotationTargetIfNeeded(mode)) { 604 annotation.rollbackTo(); 605 myBuilder.restoreNewlinesState(); 606 return false; 607 } 608 609 assert _at(LBRACKET); 610 advance(); // LBRACKET 611 612 if (!at(IDENTIFIER) && !at(AT)) { 613 error("Expecting a list of annotations"); 614 } 615 else { 616 while (at(IDENTIFIER) || at(AT)) { 617 if (at(AT)) { 618 errorAndAdvance("No '@' needed in annotation list"); // AT 619 continue; 620 } 621 622 parseAnnotation(IN_ANNOTATION_LIST); 623 while (at(COMMA)) { 624 errorAndAdvance("No commas needed to separate annotations"); 625 } 626 } 627 } 628 629 expect(RBRACKET, "Expecting ']' to close the annotation list"); 630 myBuilder.restoreNewlinesState(); 631 632 annotation.done(ANNOTATION); 633 return true; 634 } 635 636 // Returns true if we should continue parse annotation 637 private boolean parseAnnotationTargetIfNeeded(AnnotationParsingMode mode) { 638 String expectedAnnotationTargetBeforeColon = "Expected annotation target before ':'"; 639 640 if (at(COLON)) { 641 // recovery for "@:ann" 642 errorAndAdvance(expectedAnnotationTargetBeforeColon); // COLON 643 return true; 644 } 645 646 KtKeywordToken targetKeyword = atTargetKeyword(); 647 if (mode == FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED && !(targetKeyword == FILE_KEYWORD && lookahead(1) == COLON)) { 648 return false; 649 } 650 651 if (lookahead(1) == COLON && targetKeyword == null && at(IDENTIFIER)) { 652 // recovery for "@fil:ann" 653 errorAndAdvance(expectedAnnotationTargetBeforeColon); // IDENTIFIER 654 advance(); // COLON 655 return true; 656 } 657 658 if (targetKeyword == null && mode.isFileAnnotationParsingMode) { 659 parseAnnotationTarget(mode, FILE_KEYWORD); 660 } 661 else if (targetKeyword != null) { 662 parseAnnotationTarget(mode, targetKeyword); 663 } 664 665 return true; 666 } 667 668 private void parseAnnotationTarget(AnnotationParsingMode mode, KtKeywordToken keyword) { 669 if (keyword == FILE_KEYWORD && !mode.isFileAnnotationParsingMode && at(keyword) && lookahead(1) == COLON) { 670 errorAndAdvance(AT.getValue() + keyword.getValue() + " annotations are only allowed before package declaration", 2); 671 return; 672 } 673 674 String message = "Expecting \"" + keyword.getValue() + COLON.getValue() + "\" prefix for " + keyword.getValue() + " annotations"; 675 676 PsiBuilder.Marker marker = mark(); 677 678 if (!expect(keyword, message)) { 679 marker.drop(); 680 } 681 else { 682 marker.done(ANNOTATION_TARGET); 683 } 684 685 expect(COLON, message, TokenSet.create(IDENTIFIER, RBRACKET, LBRACKET)); 686 } 687 688 @Nullable 689 private KtKeywordToken atTargetKeyword() { 690 for (IElementType target : ANNOTATION_TARGETS.getTypes()) { 691 if (at(target)) return (KtKeywordToken) target; 692 } 693 return null; 694 } 695 696 /* 697 * annotation 698 * : "@" (annotationUseSiteTarget ":")? unescapedAnnotation 699 * ; 700 * 701 * unescapedAnnotation 702 * : SimpleName{"."} typeArguments? valueArguments? 703 * ; 704 */ 705 private boolean parseAnnotation(AnnotationParsingMode mode) { 706 assert _at(IDENTIFIER) || 707 (_at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(1))); 708 709 PsiBuilder.Marker annotation = mark(); 710 711 boolean atAt = at(AT); 712 if (atAt) { 713 advance(); // AT 714 } 715 716 if (atAt && !parseAnnotationTargetIfNeeded(mode)) { 717 annotation.rollbackTo(); 718 return false; 719 } 720 721 PsiBuilder.Marker reference = mark(); 722 PsiBuilder.Marker typeReference = mark(); 723 parseUserType(); 724 typeReference.done(TYPE_REFERENCE); 725 reference.done(CONSTRUCTOR_CALLEE); 726 727 parseTypeArgumentList(); 728 729 if (at(LPAR)) { 730 myExpressionParsing.parseValueArgumentList(); 731 } 732 annotation.done(ANNOTATION_ENTRY); 733 734 return true; 735 } 736 737 public enum NameParsingMode { 738 REQUIRED, 739 ALLOWED, 740 PROHIBITED 741 } 742 743 public enum DeclarationParsingMode { 744 TOP_LEVEL, 745 CLASS_MEMBER, 746 LOCAL 747 } 748 749 /* 750 * class 751 * : modifiers ("class" | "interface") SimpleName 752 * typeParameters? 753 * primaryConstructor? 754 * (":" annotations delegationSpecifier{","})? 755 * typeConstraints 756 * (classBody? | enumClassBody) 757 * ; 758 * 759 * primaryConstructor 760 * : (modifiers "constructor")? ("(" functionParameter{","} ")") 761 * ; 762 * 763 * object 764 * : "object" SimpleName? primaryConstructor? ":" delegationSpecifier{","}? classBody? 765 * ; 766 */ 767 IElementType parseClassOrObject( 768 boolean object, 769 NameParsingMode nameParsingMode, 770 boolean optionalBody, 771 boolean enumClass, 772 DeclarationParsingMode declarationParsingMode 773 ) { 774 if (object) { 775 assert _at(OBJECT_KEYWORD); 776 } 777 else { 778 assert _atSet(CLASS_KEYWORD, INTERFACE_KEYWORD); 779 } 780 advance(); // CLASS_KEYWORD, INTERFACE_KEYWORD or OBJECT_KEYWORD 781 782 if (nameParsingMode == NameParsingMode.REQUIRED) { 783 OptionalMarker marker = new OptionalMarker(object); 784 expect(IDENTIFIER, "Name expected", CLASS_NAME_RECOVERY_SET); 785 marker.done(OBJECT_DECLARATION_NAME); 786 } 787 else { 788 assert object : "Must be an object to be nameless"; 789 if (at(IDENTIFIER)) { 790 if (nameParsingMode == NameParsingMode.PROHIBITED) { 791 errorAndAdvance("An object expression cannot bind a name"); 792 } 793 else { 794 assert nameParsingMode == NameParsingMode.ALLOWED; 795 PsiBuilder.Marker marker = mark(); 796 advance(); 797 marker.done(OBJECT_DECLARATION_NAME); 798 } 799 } 800 } 801 802 OptionalMarker typeParamsMarker = new OptionalMarker(object); 803 boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET); 804 typeParamsMarker.error("Type parameters are not allowed for objects"); 805 806 PsiBuilder.Marker beforeConstructorModifiers = mark(); 807 PsiBuilder.Marker primaryConstructorMarker = mark(); 808 boolean hasConstructorModifiers = parseModifierList(DEFAULT, TokenSet.EMPTY); 809 810 // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else 811 if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD)) { 812 beforeConstructorModifiers.rollbackTo(); 813 return object ? OBJECT_DECLARATION : CLASS; 814 } 815 816 // We are still inside a class declaration 817 beforeConstructorModifiers.drop(); 818 819 boolean hasConstructorKeyword = at(CONSTRUCTOR_KEYWORD); 820 if (hasConstructorKeyword) { 821 advance(); // CONSTRUCTOR_KEYWORD 822 } 823 824 if (at(LPAR)) { 825 parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(LBRACE, RBRACE)); 826 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR); 827 } 828 else if (hasConstructorModifiers || hasConstructorKeyword) { 829 // A comprehensive error message for cases like: 830 // class A private : Foo 831 // or 832 // class A private { 833 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR); 834 if (hasConstructorKeyword) { 835 error("Expecting primary constructor parameter list"); 836 } 837 else { 838 error("Expecting 'constructor' keyword"); 839 } 840 } 841 else { 842 primaryConstructorMarker.drop(); 843 } 844 845 if (at(COLON)) { 846 advance(); // COLON 847 parseDelegationSpecifierList(); 848 } 849 850 OptionalMarker whereMarker = new OptionalMarker(object); 851 parseTypeConstraintsGuarded(typeParametersDeclared); 852 whereMarker.error("Where clause is not allowed for objects"); 853 854 if (at(LBRACE)) { 855 if (enumClass) { 856 parseEnumClassBody(); 857 } 858 else { 859 parseClassBody(); 860 } 861 } 862 else if (!optionalBody) { 863 PsiBuilder.Marker fakeBody = mark(); 864 error("Expecting a class body"); 865 fakeBody.done(CLASS_BODY); 866 } 867 868 return object ? OBJECT_DECLARATION : CLASS; 869 } 870 871 IElementType parseClass(boolean enumClass, DeclarationParsingMode declarationParsingMode) { 872 return parseClassOrObject(false, NameParsingMode.REQUIRED, true, enumClass, declarationParsingMode); 873 } 874 875 void parseObject(NameParsingMode nameParsingMode, boolean optionalBody, DeclarationParsingMode declarationParsingMode) { 876 parseClassOrObject(true, nameParsingMode, optionalBody, false, declarationParsingMode); 877 } 878 879 /* 880 * enumClassBody 881 * : "{" enumEntries (";" members)? "}" 882 * ; 883 */ 884 private void parseEnumClassBody() { 885 if (!at(LBRACE)) return; 886 887 PsiBuilder.Marker body = mark(); 888 myBuilder.enableNewlines(); 889 890 advance(); // LBRACE 891 892 if (!parseEnumEntries() && !at(RBRACE)) { 893 error("Expecting ';' after the last enum entry or '}' to close enum class body"); 894 } 895 parseMembers(); 896 expect(RBRACE, "Expecting '}' to close enum class body"); 897 898 myBuilder.restoreNewlinesState(); 899 body.done(CLASS_BODY); 900 } 901 902 /** 903 * enumEntries 904 * : enumEntry{","}? 905 * ; 906 * 907 * @return true if enum regular members can follow, false otherwise 908 */ 909 private boolean parseEnumEntries() { 910 while (!eof() && !at(RBRACE)) { 911 switch (parseEnumEntry()) { 912 case FAILED: 913 // Special case without any enum entries but with possible members after semicolon 914 if (at(SEMICOLON)) { 915 advance(); 916 return true; 917 } 918 else { 919 return false; 920 } 921 case NO_DELIMITER: 922 return false; 923 case COMMA_DELIMITER: 924 break; 925 case SEMICOLON_DELIMITER: 926 return true; 927 } 928 } 929 return false; 930 } 931 932 private enum ParseEnumEntryResult { 933 FAILED, 934 NO_DELIMITER, 935 COMMA_DELIMITER, 936 SEMICOLON_DELIMITER 937 } 938 939 /* 940 * enumEntry 941 * : modifiers SimpleName ("(" arguments ")")? classBody? 942 * ; 943 */ 944 private ParseEnumEntryResult parseEnumEntry() { 945 PsiBuilder.Marker entry = mark(); 946 947 parseModifierList(DEFAULT, TokenSet.create(COMMA, SEMICOLON, RBRACE)); 948 949 if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) { 950 PsiBuilder.Marker nameAsDeclaration = mark(); 951 advance(); // IDENTIFIER 952 nameAsDeclaration.done(OBJECT_DECLARATION_NAME); 953 954 if (at(LPAR)) { 955 // Arguments should be parsed here 956 // Also, "fake" constructor call tree is created, 957 // with empty type name inside 958 PsiBuilder.Marker initializerList = mark(); 959 PsiBuilder.Marker delegatorSuperCall = mark(); 960 961 PsiBuilder.Marker callee = mark(); 962 PsiBuilder.Marker typeReference = mark(); 963 PsiBuilder.Marker type = mark(); 964 PsiBuilder.Marker referenceExpr = mark(); 965 referenceExpr.done(ENUM_ENTRY_SUPERCLASS_REFERENCE_EXPRESSION); 966 type.done(USER_TYPE); 967 typeReference.done(TYPE_REFERENCE); 968 callee.done(CONSTRUCTOR_CALLEE); 969 970 myExpressionParsing.parseValueArgumentList(); 971 delegatorSuperCall.done(DELEGATOR_SUPER_CALL); 972 initializerList.done(INITIALIZER_LIST); 973 } 974 if (at(LBRACE)) { 975 parseClassBody(); 976 } 977 boolean commaFound = at(COMMA); 978 if (commaFound) { 979 advance(); 980 } 981 boolean semicolonFound = at(SEMICOLON); 982 if (semicolonFound) { 983 advance(); 984 } 985 986 // Probably some helper function 987 closeDeclarationWithCommentBinders(entry, ENUM_ENTRY, true); 988 return semicolonFound 989 ? ParseEnumEntryResult.SEMICOLON_DELIMITER 990 : (commaFound ? ParseEnumEntryResult.COMMA_DELIMITER : ParseEnumEntryResult.NO_DELIMITER); 991 } 992 else { 993 entry.rollbackTo(); 994 return ParseEnumEntryResult.FAILED; 995 } 996 } 997 998 /* 999 * classBody 1000 * : ("{" members "}")? 1001 * ; 1002 */ 1003 private void parseClassBody() { 1004 PsiBuilder.Marker body = mark(); 1005 1006 myBuilder.enableNewlines(); 1007 1008 if (expect(LBRACE, "Expecting a class body")) { 1009 parseMembers(); 1010 expect(RBRACE, "Missing '}"); 1011 } 1012 1013 myBuilder.restoreNewlinesState(); 1014 1015 body.done(CLASS_BODY); 1016 } 1017 1018 /** 1019 * members 1020 * : memberDeclaration* 1021 * ; 1022 */ 1023 private void parseMembers() { 1024 while (!eof() && !at(RBRACE)) { 1025 parseMemberDeclaration(); 1026 } 1027 } 1028 1029 /* 1030 * memberDeclaration 1031 * : modifiers memberDeclaration' 1032 * ; 1033 * 1034 * memberDeclaration' 1035 * : companionObject 1036 * : secondaryConstructor 1037 * : function 1038 * : property 1039 * : class 1040 * : extension 1041 * : typeAlias 1042 * : anonymousInitializer 1043 * : object 1044 * ; 1045 */ 1046 private void parseMemberDeclaration() { 1047 if (at(SEMICOLON)) { 1048 advance(); // SEMICOLON 1049 return; 1050 } 1051 PsiBuilder.Marker decl = mark(); 1052 1053 ModifierDetector detector = new ModifierDetector(); 1054 parseModifierList(detector, DEFAULT, TokenSet.EMPTY); 1055 1056 IElementType declType = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected()); 1057 1058 if (declType == null) { 1059 errorWithRecovery("Expecting member declaration", TokenSet.EMPTY); 1060 decl.drop(); 1061 } 1062 else { 1063 closeDeclarationWithCommentBinders(decl, declType, true); 1064 } 1065 } 1066 1067 private IElementType parseMemberDeclarationRest(boolean isEnum, boolean isDefault) { 1068 IElementType keywordToken = tt(); 1069 IElementType declType = null; 1070 if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) { 1071 declType = parseClass(isEnum, CLASS_MEMBER); 1072 } 1073 else if (keywordToken == FUN_KEYWORD) { 1074 declType = parseFunction(); 1075 } 1076 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { 1077 declType = parseProperty(); 1078 } 1079 else if (keywordToken == TYPE_ALIAS_KEYWORD) { 1080 declType = parseTypeAlias(); 1081 } 1082 else if (keywordToken == OBJECT_KEYWORD) { 1083 parseObject(isDefault ? NameParsingMode.ALLOWED : NameParsingMode.REQUIRED, true, CLASS_MEMBER); 1084 declType = OBJECT_DECLARATION; 1085 } 1086 else if (at(INIT_KEYWORD)) { 1087 advance(); // init 1088 if (at(LBRACE)) { 1089 parseBlock(); 1090 } 1091 else { 1092 mark().error("Expecting '{' after 'init'"); 1093 } 1094 declType = ANONYMOUS_INITIALIZER; 1095 } 1096 else if (at(CONSTRUCTOR_KEYWORD)) { 1097 parseSecondaryConstructor(); 1098 declType = SECONDARY_CONSTRUCTOR; 1099 } 1100 else if (at(LBRACE)) { 1101 error("Expecting member declaration"); 1102 parseBlock(); 1103 declType = FUN; 1104 } 1105 return declType; 1106 } 1107 1108 /* 1109 * secondaryConstructor 1110 * : modifiers "constructor" valueParameters (":" constructorDelegationCall)? block 1111 * constructorDelegationCall 1112 * : "this" valueArguments 1113 * : "super" valueArguments 1114 */ 1115 private void parseSecondaryConstructor() { 1116 assert _at(CONSTRUCTOR_KEYWORD); 1117 1118 advance(); // CONSTRUCTOR_KEYWORD 1119 1120 TokenSet valueArgsRecoverySet = TokenSet.create(LBRACE, SEMICOLON, RPAR, EOL_OR_SEMICOLON, RBRACE); 1121 if (at(LPAR)) { 1122 parseValueParameterList(false, /*typeRequired = */ true, valueArgsRecoverySet); 1123 } 1124 else { 1125 errorWithRecovery("Expecting '('", TokenSet.orSet(valueArgsRecoverySet, TokenSet.create(COLON))); 1126 } 1127 1128 if (at(COLON)) { 1129 advance(); // COLON 1130 1131 PsiBuilder.Marker delegationCall = mark(); 1132 1133 if (at(THIS_KEYWORD) || at(SUPER_KEYWORD)) { 1134 parseThisOrSuper(); 1135 myExpressionParsing.parseValueArgumentList(); 1136 } 1137 else { 1138 error("Expecting a 'this' or 'super' constructor call"); 1139 PsiBuilder.Marker beforeWrongDelegationCallee = null; 1140 if (!at(LPAR)) { 1141 beforeWrongDelegationCallee = mark(); 1142 advance(); // wrong delegation callee 1143 } 1144 myExpressionParsing.parseValueArgumentList(); 1145 1146 if (beforeWrongDelegationCallee != null) { 1147 if (at(LBRACE)) { 1148 beforeWrongDelegationCallee.drop(); 1149 } 1150 else { 1151 beforeWrongDelegationCallee.rollbackTo(); 1152 } 1153 } 1154 } 1155 1156 delegationCall.done(CONSTRUCTOR_DELEGATION_CALL); 1157 } 1158 else { 1159 // empty constructor delegation call 1160 PsiBuilder.Marker emptyDelegationCall = mark(); 1161 mark().done(CONSTRUCTOR_DELEGATION_REFERENCE); 1162 emptyDelegationCall.done(CONSTRUCTOR_DELEGATION_CALL); 1163 } 1164 1165 if (at(LBRACE)) { 1166 parseBlock(); 1167 } 1168 } 1169 1170 private void parseThisOrSuper() { 1171 assert _at(THIS_KEYWORD) || _at(SUPER_KEYWORD); 1172 PsiBuilder.Marker mark = mark(); 1173 1174 advance(); // THIS_KEYWORD | SUPER_KEYWORD 1175 1176 mark.done(CONSTRUCTOR_DELEGATION_REFERENCE); 1177 } 1178 1179 /* 1180 * typeAlias 1181 * : modifiers "typealias" SimpleName (typeParameters typeConstraints)? "=" type 1182 * ; 1183 */ 1184 KtNodeType parseTypeAlias() { 1185 assert _at(TYPE_ALIAS_KEYWORD); 1186 1187 advance(); // TYPE_ALIAS_KEYWORD 1188 1189 expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOP_LEVEL_DECLARATION_FIRST)); 1190 1191 if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) { 1192 parseTypeConstraints(); 1193 } 1194 1195 expect(EQ, "Expecting '='", TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, TokenSet.create(SEMICOLON))); 1196 1197 parseTypeRef(); 1198 1199 consumeIf(SEMICOLON); 1200 1201 return TYPEDEF; 1202 } 1203 1204 /* 1205 * variableDeclarationEntry 1206 * : SimpleName (":" type)? 1207 * ; 1208 * 1209 * property 1210 * : modifiers ("val" | "var") 1211 * typeParameters? (type "." | annotations)? 1212 * ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry) 1213 * typeConstraints 1214 * ("by" | "=" expression SEMI?)? 1215 * (getter? setter? | setter? getter?) SEMI? 1216 * ; 1217 */ 1218 private IElementType parseProperty() { 1219 return parseProperty(false); 1220 } 1221 1222 public IElementType parseProperty(boolean local) { 1223 assert (at(VAL_KEYWORD) || at(VAR_KEYWORD)); 1224 advance(); 1225 1226 boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON)); 1227 1228 TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD); 1229 1230 myBuilder.disableJoiningComplexTokens(); 1231 1232 PsiBuilder.Marker receiver = mark(); 1233 boolean receiverTypeDeclared = parseReceiverType("property", propertyNameFollow); 1234 1235 boolean multiDeclaration = at(LPAR); 1236 1237 errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration"); 1238 1239 if (multiDeclaration) { 1240 PsiBuilder.Marker multiDecl = mark(); 1241 parseMultiDeclarationName(propertyNameFollow); 1242 errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values"); 1243 } 1244 else { 1245 parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow, /*nameRequired = */ false); 1246 } 1247 1248 myBuilder.restoreJoiningComplexTokensState(); 1249 1250 if (at(COLON)) { 1251 PsiBuilder.Marker type = mark(); 1252 advance(); // COLON 1253 parseTypeRef(); 1254 errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations"); 1255 } 1256 1257 parseTypeConstraintsGuarded(typeParametersDeclared); 1258 1259 if (local) { 1260 if (at(BY_KEYWORD)) { 1261 parsePropertyDelegate(); 1262 } 1263 else if (at(EQ)) { 1264 advance(); // EQ 1265 myExpressionParsing.parseExpression(); 1266 // "val a = 1; b" must not be an infix call of b on "val ...;" 1267 } 1268 } 1269 else { 1270 if (at(BY_KEYWORD)) { 1271 parsePropertyDelegate(); 1272 consumeIf(SEMICOLON); 1273 } 1274 else if (at(EQ)) { 1275 advance(); // EQ 1276 myExpressionParsing.parseExpression(); 1277 consumeIf(SEMICOLON); 1278 } 1279 1280 if (parsePropertyGetterOrSetter()) { 1281 parsePropertyGetterOrSetter(); 1282 } 1283 if (!atSet(EOL_OR_SEMICOLON, RBRACE)) { 1284 if (getLastToken() != SEMICOLON) { 1285 errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE)); 1286 } 1287 } 1288 else { 1289 consumeIf(SEMICOLON); 1290 } 1291 } 1292 1293 return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY; 1294 } 1295 1296 /* 1297 * propertyDelegate 1298 * : "by" expression 1299 * ; 1300 */ 1301 private void parsePropertyDelegate() { 1302 assert _at(BY_KEYWORD); 1303 PsiBuilder.Marker delegate = mark(); 1304 advance(); // BY_KEYWORD 1305 myExpressionParsing.parseExpression(); 1306 delegate.done(PROPERTY_DELEGATE); 1307 } 1308 1309 /* 1310 * (SimpleName (":" type)){","} 1311 */ 1312 public void parseMultiDeclarationName(TokenSet follow) { 1313 // Parsing multi-name, e.g. 1314 // val (a, b) = foo() 1315 myBuilder.disableNewlines(); 1316 advance(); // LPAR 1317 1318 TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow); 1319 if (!atSet(follow)) { 1320 while (true) { 1321 if (at(COMMA)) { 1322 errorAndAdvance("Expecting a name"); 1323 } 1324 else if (at(RPAR)) { 1325 error("Expecting a name"); 1326 break; 1327 } 1328 PsiBuilder.Marker property = mark(); 1329 1330 parseModifierList(DEFAULT, TokenSet.create(COMMA, RPAR, COLON, EQ)); 1331 1332 expect(IDENTIFIER, "Expecting a name", recoverySet); 1333 1334 if (at(COLON)) { 1335 advance(); // COLON 1336 parseTypeRef(follow); 1337 } 1338 property.done(MULTI_VARIABLE_DECLARATION_ENTRY); 1339 1340 if (!at(COMMA)) break; 1341 advance(); // COMMA 1342 } 1343 } 1344 1345 expect(RPAR, "Expecting ')'", follow); 1346 myBuilder.restoreNewlinesState(); 1347 } 1348 1349 /* 1350 * getterOrSetter 1351 * : modifiers ("get" | "set") 1352 * : 1353 * ( "get" "(" ")" 1354 * | 1355 * "set" "(" modifiers parameter ")" 1356 * ) functionBody 1357 * ; 1358 */ 1359 private boolean parsePropertyGetterOrSetter() { 1360 PsiBuilder.Marker getterOrSetter = mark(); 1361 1362 parseModifierList(DEFAULT, TokenSet.EMPTY); 1363 1364 if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) { 1365 getterOrSetter.rollbackTo(); 1366 return false; 1367 } 1368 1369 boolean setter = at(SET_KEYWORD); 1370 advance(); // GET_KEYWORD or SET_KEYWORD 1371 1372 if (!at(LPAR)) { 1373 // Account for Jet-114 (val a : int get {...}) 1374 TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(AT, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE)); 1375 if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) { 1376 errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ))); 1377 } 1378 else { 1379 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false); 1380 return true; 1381 } 1382 } 1383 1384 myBuilder.disableNewlines(); 1385 expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ)); 1386 if (setter) { 1387 PsiBuilder.Marker parameterList = mark(); 1388 PsiBuilder.Marker setterParameter = mark(); 1389 parseModifierList(DEFAULT, TokenSet.create(COMMA, COLON, RPAR)); 1390 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ)); 1391 1392 if (at(COLON)) { 1393 advance(); // COLON 1394 parseTypeRef(); 1395 } 1396 setterParameter.done(VALUE_PARAMETER); 1397 parameterList.done(VALUE_PARAMETER_LIST); 1398 } 1399 if (!at(RPAR)) { 1400 errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, RBRACE, EQ, EOL_OR_SEMICOLON)); 1401 } 1402 if (at(RPAR)) { 1403 advance(); 1404 } 1405 myBuilder.restoreNewlinesState(); 1406 1407 if (at(COLON)) { 1408 advance(); 1409 1410 parseTypeRef(); 1411 } 1412 1413 parseFunctionBody(); 1414 1415 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false); 1416 1417 return true; 1418 } 1419 1420 /* 1421 * function 1422 * : modifiers "fun" typeParameters? 1423 * (type "." | annotations)? 1424 * SimpleName 1425 * typeParameters? functionParameters (":" type)? 1426 * typeConstraints 1427 * functionBody? 1428 * ; 1429 */ 1430 IElementType parseFunction() { 1431 assert _at(FUN_KEYWORD); 1432 1433 advance(); // FUN_KEYWORD 1434 1435 // Recovery for the case of class A { fun| } 1436 if (at(RBRACE)) { 1437 error("Function body expected"); 1438 return FUN; 1439 } 1440 1441 boolean typeParameterListOccurred = false; 1442 if (at(LT)) { 1443 parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, RBRACE, LPAR)); 1444 typeParameterListOccurred = true; 1445 } 1446 1447 myBuilder.disableJoiningComplexTokens(); 1448 1449 TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ); 1450 boolean receiverFound = parseReceiverType("function", functionNameFollow); 1451 1452 // function as expression has no name 1453 parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ true); 1454 1455 myBuilder.restoreJoiningComplexTokensState(); 1456 1457 TokenSet valueParametersFollow = TokenSet.create(EQ, LBRACE, RBRACE, SEMICOLON, RPAR); 1458 1459 if (at(LT)) { 1460 PsiBuilder.Marker error = mark(); 1461 parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow)); 1462 errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function"); 1463 typeParameterListOccurred = true; 1464 } 1465 1466 if (at(LPAR)) { 1467 parseValueParameterList(false, /* typeRequired = */ false, valueParametersFollow); 1468 } 1469 else { 1470 error("Expecting '('"); 1471 } 1472 1473 if (at(COLON)) { 1474 advance(); // COLON 1475 1476 parseTypeRef(); 1477 } 1478 1479 parseTypeConstraintsGuarded(typeParameterListOccurred); 1480 1481 if (at(SEMICOLON)) { 1482 advance(); // SEMICOLON 1483 } 1484 else if (at(EQ) || at(LBRACE)) { 1485 parseFunctionBody(); 1486 } 1487 1488 return FUN; 1489 } 1490 1491 /* 1492 * (type "." | annotations)? 1493 */ 1494 private boolean parseReceiverType(String title, TokenSet nameFollow) { 1495 PsiBuilder.Marker annotations = mark(); 1496 boolean annotationsPresent = parseAnnotations(DEFAULT); 1497 int lastDot = lastDotAfterReceiver(); 1498 boolean receiverPresent = lastDot != -1; 1499 if (annotationsPresent) { 1500 if (receiverPresent) { 1501 annotations.rollbackTo(); 1502 } 1503 else { 1504 annotations.error("Annotations are not allowed in this position"); 1505 } 1506 } 1507 else { 1508 annotations.drop(); 1509 } 1510 1511 if (!receiverPresent) return false; 1512 1513 createTruncatedBuilder(lastDot).parseTypeRef(); 1514 1515 if (atSet(RECEIVER_TYPE_TERMINATORS)) { 1516 advance(); // expectation 1517 } 1518 else { 1519 errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow); 1520 } 1521 return true; 1522 } 1523 1524 private int lastDotAfterReceiver() { 1525 if (at(LPAR)) { 1526 return matchTokenStreamPredicate( 1527 new FirstBefore( 1528 new AtSet(RECEIVER_TYPE_TERMINATORS), 1529 new AbstractTokenStreamPredicate() { 1530 @Override 1531 public boolean matching(boolean topLevel) { 1532 if (topLevel && definitelyOutOfReceiver()) { 1533 return true; 1534 } 1535 return topLevel && !at(QUEST) && !at(LPAR) && !at(RPAR); 1536 } 1537 } 1538 )); 1539 } 1540 else { 1541 return matchTokenStreamPredicate( 1542 new LastBefore( 1543 new AtSet(RECEIVER_TYPE_TERMINATORS), 1544 new AbstractTokenStreamPredicate() { 1545 @Override 1546 public boolean matching(boolean topLevel) { 1547 if (topLevel && (definitelyOutOfReceiver() || at(LPAR))) return true; 1548 if (topLevel && at(IDENTIFIER)) { 1549 IElementType lookahead = lookahead(1); 1550 return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST; 1551 } 1552 return false; 1553 } 1554 })); 1555 } 1556 } 1557 1558 private boolean definitelyOutOfReceiver() { 1559 return atSet(EQ, COLON, LBRACE, RBRACE, BY_KEYWORD) || atSet(TOP_LEVEL_DECLARATION_FIRST); 1560 } 1561 1562 /* 1563 * IDENTIFIER 1564 */ 1565 private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) { 1566 if (nameRequired && atSet(nameFollow)) return; // no name 1567 1568 TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE)); 1569 if (!receiverFound) { 1570 expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet); 1571 } 1572 else { 1573 expect(IDENTIFIER, "Expecting " + title + " name", recoverySet); 1574 } 1575 } 1576 1577 /* 1578 * functionBody 1579 * : block 1580 * : "=" element 1581 * ; 1582 */ 1583 private void parseFunctionBody() { 1584 if (at(LBRACE)) { 1585 parseBlock(); 1586 } 1587 else if (at(EQ)) { 1588 advance(); // EQ 1589 myExpressionParsing.parseExpression(); 1590 consumeIf(SEMICOLON); 1591 } 1592 else { 1593 error("Expecting function body"); 1594 } 1595 } 1596 1597 /* 1598 * block 1599 * : "{" (expressions)* "}" 1600 * ; 1601 */ 1602 void parseBlock() { 1603 PsiBuilder.Marker block = mark(); 1604 1605 myBuilder.enableNewlines(); 1606 expect(LBRACE, "Expecting '{' to open a block"); 1607 1608 myExpressionParsing.parseStatements(); 1609 1610 expect(RBRACE, "Expecting '}'"); 1611 myBuilder.restoreNewlinesState(); 1612 1613 block.done(BLOCK); 1614 } 1615 1616 /* 1617 * delegationSpecifier{","} 1618 */ 1619 /*package*/ void parseDelegationSpecifierList() { 1620 PsiBuilder.Marker list = mark(); 1621 1622 while (true) { 1623 if (at(COMMA)) { 1624 errorAndAdvance("Expecting a delegation specifier"); 1625 continue; 1626 } 1627 parseDelegationSpecifier(); 1628 if (!at(COMMA)) break; 1629 advance(); // COMMA 1630 } 1631 1632 list.done(DELEGATION_SPECIFIER_LIST); 1633 } 1634 1635 /* 1636 * delegationSpecifier 1637 * : constructorInvocation // type and constructor arguments 1638 * : userType 1639 * : explicitDelegation 1640 * ; 1641 * 1642 * explicitDelegation 1643 * : userType "by" element 1644 * ; 1645 */ 1646 private void parseDelegationSpecifier() { 1647 PsiBuilder.Marker delegator = mark(); 1648 PsiBuilder.Marker reference = mark(); 1649 parseTypeRef(); 1650 1651 if (at(BY_KEYWORD)) { 1652 reference.drop(); 1653 advance(); // BY_KEYWORD 1654 createForByClause(myBuilder).myExpressionParsing.parseExpression(); 1655 delegator.done(DELEGATOR_BY); 1656 } 1657 else if (at(LPAR)) { 1658 reference.done(CONSTRUCTOR_CALLEE); 1659 myExpressionParsing.parseValueArgumentList(); 1660 delegator.done(DELEGATOR_SUPER_CALL); 1661 } 1662 else { 1663 reference.drop(); 1664 delegator.done(DELEGATOR_SUPER_CLASS); 1665 } 1666 } 1667 1668 /* 1669 * typeParameters 1670 * : ("<" typeParameter{","} ">" 1671 * ; 1672 */ 1673 private boolean parseTypeParameterList(TokenSet recoverySet) { 1674 boolean result = false; 1675 if (at(LT)) { 1676 PsiBuilder.Marker list = mark(); 1677 1678 myBuilder.disableNewlines(); 1679 advance(); // LT 1680 1681 while (true) { 1682 if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration"); 1683 parseTypeParameter(); 1684 1685 if (!at(COMMA)) break; 1686 advance(); // COMMA 1687 } 1688 1689 expect(GT, "Missing '>'", recoverySet); 1690 myBuilder.restoreNewlinesState(); 1691 result = true; 1692 1693 list.done(TYPE_PARAMETER_LIST); 1694 } 1695 return result; 1696 } 1697 1698 /* 1699 * typeConstraints 1700 * : ("where" typeConstraint{","})? 1701 * ; 1702 */ 1703 private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) { 1704 PsiBuilder.Marker error = mark(); 1705 boolean constraints = parseTypeConstraints(); 1706 errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared"); 1707 } 1708 1709 private boolean parseTypeConstraints() { 1710 if (at(WHERE_KEYWORD)) { 1711 parseTypeConstraintList(); 1712 return true; 1713 } 1714 return false; 1715 } 1716 1717 /* 1718 * typeConstraint{","} 1719 */ 1720 private void parseTypeConstraintList() { 1721 assert _at(WHERE_KEYWORD); 1722 1723 advance(); // WHERE_KEYWORD 1724 1725 PsiBuilder.Marker list = mark(); 1726 1727 while (true) { 1728 if (at(COMMA)) errorAndAdvance("Type constraint expected"); 1729 parseTypeConstraint(); 1730 if (!at(COMMA)) break; 1731 advance(); // COMMA 1732 } 1733 1734 list.done(TYPE_CONSTRAINT_LIST); 1735 } 1736 1737 /* 1738 * typeConstraint 1739 * : annotations SimpleName ":" type 1740 * ; 1741 */ 1742 private void parseTypeConstraint() { 1743 PsiBuilder.Marker constraint = mark(); 1744 1745 parseAnnotations(DEFAULT); 1746 1747 PsiBuilder.Marker reference = mark(); 1748 if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA, LBRACE, RBRACE), TYPE_REF_FIRST))) { 1749 reference.done(REFERENCE_EXPRESSION); 1750 } 1751 else { 1752 reference.drop(); 1753 } 1754 1755 expect(COLON, "Expecting ':' before the upper bound", TokenSet.orSet(TokenSet.create(LBRACE, RBRACE), TYPE_REF_FIRST)); 1756 1757 parseTypeRef(); 1758 1759 constraint.done(TYPE_CONSTRAINT); 1760 } 1761 1762 /* 1763 * typeParameter 1764 * : modifiers SimpleName (":" userType)? 1765 * ; 1766 */ 1767 private void parseTypeParameter() { 1768 if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) { 1769 error("Type parameter declaration expected"); 1770 return; 1771 } 1772 1773 PsiBuilder.Marker mark = mark(); 1774 1775 parseModifierList(DEFAULT, TokenSet.create(GT, COMMA, COLON)); 1776 1777 expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY); 1778 1779 if (at(COLON)) { 1780 advance(); // COLON 1781 parseTypeRef(); 1782 } 1783 1784 mark.done(TYPE_PARAMETER); 1785 1786 } 1787 1788 /* 1789 * type 1790 * : annotations typeDescriptor 1791 * 1792 * typeDescriptor 1793 * : selfType 1794 * : functionType 1795 * : userType 1796 * : nullableType 1797 * : "dynamic" 1798 * ; 1799 * 1800 * nullableType 1801 * : typeDescriptor "?" 1802 */ 1803 void parseTypeRef() { 1804 parseTypeRef(TokenSet.EMPTY); 1805 } 1806 1807 void parseTypeRef(TokenSet extraRecoverySet) { 1808 PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet); 1809 typeRefMarker.done(TYPE_REFERENCE); 1810 } 1811 1812 // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop 1813 // on expression-indicating symbols or not 1814 private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) { 1815 PsiBuilder.Marker typeRefMarker = mark(); 1816 parseAnnotations(DEFAULT); 1817 1818 PsiBuilder.Marker typeElementMarker = mark(); 1819 1820 IElementType lookahead = lookahead(1); 1821 IElementType lookahead2 = lookahead(2); 1822 boolean typeBeforeDot = true; 1823 if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) { 1824 PsiBuilder.Marker dynamicType = mark(); 1825 advance(); // DYNAMIC_KEYWORD 1826 dynamicType.done(DYNAMIC_TYPE); 1827 } 1828 else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) { 1829 parseUserType(); 1830 } 1831 else if (at(LPAR)) { 1832 PsiBuilder.Marker functionOrParenthesizedType = mark(); 1833 1834 // This may be a function parameter list or just a prenthesized type 1835 advance(); // LPAR 1836 parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed 1837 1838 if (at(RPAR)) { 1839 advance(); // RPAR 1840 if (at(ARROW)) { 1841 // It's a function type with one parameter specified 1842 // (A) -> B 1843 functionOrParenthesizedType.rollbackTo(); 1844 parseFunctionType(); 1845 } 1846 else { 1847 // It's a parenthesized type 1848 // (A) 1849 functionOrParenthesizedType.drop(); 1850 } 1851 } 1852 else { 1853 // This must be a function type 1854 // (A, B) -> C 1855 // or 1856 // (a : A) -> C 1857 functionOrParenthesizedType.rollbackTo(); 1858 parseFunctionType(); 1859 } 1860 1861 } 1862 else if (at(CAPITALIZED_THIS_KEYWORD)) { 1863 parseSelfType(); 1864 } 1865 else { 1866 errorWithRecovery("Type expected", 1867 TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, 1868 TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), 1869 extraRecoverySet)); 1870 typeBeforeDot = false; 1871 } 1872 1873 // Disabling token merge is required for cases like 1874 // Int?.(Foo) -> Bar 1875 myBuilder.disableJoiningComplexTokens(); 1876 typeElementMarker = parseNullableTypeSuffix(typeElementMarker); 1877 myBuilder.restoreJoiningComplexTokensState(); 1878 1879 if (typeBeforeDot && at(DOT)) { 1880 // This is a receiver for a function type 1881 // A.(B) -> C 1882 // ^ 1883 1884 PsiBuilder.Marker functionType = typeRefMarker.precede(); 1885 PsiBuilder.Marker receiverType = typeRefMarker.precede(); 1886 typeRefMarker.done(TYPE_REFERENCE); 1887 receiverType.done(FUNCTION_TYPE_RECEIVER); 1888 1889 advance(); // DOT 1890 1891 if (at(LPAR)) { 1892 parseFunctionTypeContents().drop(); 1893 } 1894 else { 1895 error("Expecting function type"); 1896 } 1897 typeRefMarker = functionType.precede(); 1898 1899 functionType.done(FUNCTION_TYPE); 1900 } 1901 1902 typeElementMarker.drop(); 1903 return typeRefMarker; 1904 } 1905 1906 @NotNull 1907 PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeElementMarker) { 1908 // ?: is joined regardless of joining state 1909 while (at(QUEST) && myBuilder.rawLookup(1) != COLON) { 1910 PsiBuilder.Marker precede = typeElementMarker.precede(); 1911 advance(); // QUEST 1912 typeElementMarker.done(NULLABLE_TYPE); 1913 typeElementMarker = precede; 1914 } 1915 return typeElementMarker; 1916 } 1917 1918 /* 1919 * userType 1920 * : ("package" ".")? simpleUserType{"."} 1921 * ; 1922 * 1923 * recovers on platform types: 1924 * - Foo! 1925 * - (Mutable)List<Foo>! 1926 * - Array<(out) Foo>! 1927 */ 1928 void parseUserType() { 1929 PsiBuilder.Marker userType = mark(); 1930 1931 if (at(PACKAGE_KEYWORD)) { 1932 advance(); // PACKAGE_KEYWORD 1933 expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER, LBRACE, RBRACE)); 1934 } 1935 1936 PsiBuilder.Marker reference = mark(); 1937 while (true) { 1938 recoverOnParenthesizedWordForPlatformTypes(0, "Mutable", true); 1939 1940 if (expect(IDENTIFIER, "Expecting type name", 1941 TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW, DECLARATION_FIRST))) { 1942 reference.done(REFERENCE_EXPRESSION); 1943 } 1944 else { 1945 reference.drop(); 1946 break; 1947 } 1948 1949 parseTypeArgumentList(); 1950 1951 recoverOnPlatformTypeSuffix(); 1952 1953 if (!at(DOT)) { 1954 break; 1955 } 1956 if (lookahead(1) == LPAR && !atParenthesizedMutableForPlatformTypes(1)) { 1957 // This may be a receiver for a function type 1958 // Int.(Int) -> Int 1959 break; 1960 } 1961 1962 PsiBuilder.Marker precede = userType.precede(); 1963 userType.done(USER_TYPE); 1964 userType = precede; 1965 1966 advance(); // DOT 1967 reference = mark(); 1968 } 1969 1970 userType.done(USER_TYPE); 1971 } 1972 1973 private boolean atParenthesizedMutableForPlatformTypes(int offset) { 1974 return recoverOnParenthesizedWordForPlatformTypes(offset, "Mutable", false); 1975 } 1976 1977 private boolean recoverOnParenthesizedWordForPlatformTypes(int offset, String word, boolean consume) { 1978 // Array<(out) Foo>! or (Mutable)List<Bar>! 1979 if (lookahead(offset) == LPAR && lookahead(offset + 1) == IDENTIFIER && lookahead(offset + 2) == RPAR && lookahead(offset + 3) == IDENTIFIER) { 1980 PsiBuilder.Marker error = mark(); 1981 1982 advance(offset); 1983 1984 advance(); // LPAR 1985 if (!word.equals(myBuilder.getTokenText())) { 1986 // something other than "out" / "Mutable" 1987 error.rollbackTo(); 1988 return false; 1989 } 1990 else { 1991 advance(); // IDENTIFIER('out') 1992 advance(); // RPAR 1993 1994 if (consume) { 1995 error.error("Unexpected tokens"); 1996 } 1997 else { 1998 error.rollbackTo(); 1999 } 2000 2001 return true; 2002 } 2003 } 2004 return false; 2005 } 2006 2007 private void recoverOnPlatformTypeSuffix() { 2008 // Recovery for platform types 2009 if (at(EXCL)) { 2010 PsiBuilder.Marker error = mark(); 2011 advance(); // EXCL 2012 error.error("Unexpected token"); 2013 } 2014 } 2015 2016 /* 2017 * selfType 2018 * : "This" 2019 * ; 2020 */ 2021 private void parseSelfType() { 2022 assert _at(CAPITALIZED_THIS_KEYWORD); 2023 2024 PsiBuilder.Marker type = mark(); 2025 advance(); // CAPITALIZED_THIS_KEYWORD 2026 type.done(SELF_TYPE); 2027 } 2028 2029 /* 2030 * (optionalProjection type){","} 2031 */ 2032 private PsiBuilder.Marker parseTypeArgumentList() { 2033 if (!at(LT)) return null; 2034 2035 PsiBuilder.Marker list = mark(); 2036 2037 tryParseTypeArgumentList(TokenSet.EMPTY); 2038 2039 list.done(TYPE_ARGUMENT_LIST); 2040 return list; 2041 } 2042 2043 boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) { 2044 myBuilder.disableNewlines(); 2045 advance(); // LT 2046 2047 while (true) { 2048 PsiBuilder.Marker projection = mark(); 2049 2050 recoverOnParenthesizedWordForPlatformTypes(0, "out", true); 2051 2052 // TokenSet lookFor = TokenSet.create(IDENTIFIER); 2053 // TokenSet stopAt = TokenSet.create(COMMA, COLON, GT); 2054 // parseModifierListWithUnescapedAnnotations(MODIFIER_LIST, lookFor, stopAt); 2055 // Currently we do not allow annotations 2056 parseModifierList(NO_ANNOTATIONS, TokenSet.create(COMMA, COLON, GT)); 2057 2058 if (at(MUL)) { 2059 advance(); // MUL 2060 } 2061 else { 2062 parseTypeRef(extraRecoverySet); 2063 } 2064 projection.done(TYPE_PROJECTION); 2065 if (!at(COMMA)) break; 2066 advance(); // COMMA 2067 } 2068 2069 boolean atGT = at(GT); 2070 if (!atGT) { 2071 error("Expecting a '>'"); 2072 } 2073 else { 2074 advance(); // GT 2075 } 2076 myBuilder.restoreNewlinesState(); 2077 return atGT; 2078 } 2079 2080 /* 2081 * functionType 2082 * : "(" (parameter | modifiers type){","}? ")" "->" type? 2083 * ; 2084 */ 2085 private void parseFunctionType() { 2086 parseFunctionTypeContents().done(FUNCTION_TYPE); 2087 } 2088 2089 private PsiBuilder.Marker parseFunctionTypeContents() { 2090 assert _at(LPAR) : tt(); 2091 PsiBuilder.Marker functionType = mark(); 2092 2093 parseValueParameterList(true, /* typeRequired = */ true, TokenSet.EMPTY); 2094 2095 expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST); 2096 parseTypeRef(); 2097 2098 return functionType; 2099 } 2100 2101 private static final TokenSet NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER = TokenSet.create(COMMA, COLON, EQ, RPAR); 2102 2103 /* 2104 * functionParameters 2105 * : "(" functionParameter{","}? ")" // default values 2106 * ; 2107 * 2108 * functionParameter 2109 * : modifiers functionParameterRest 2110 * ; 2111 * 2112 * functionParameterRest 2113 * : parameter ("=" element)? 2114 * ; 2115 */ 2116 void parseValueParameterList(boolean isFunctionTypeContents, boolean typeRequired, TokenSet recoverySet) { 2117 assert _at(LPAR); 2118 PsiBuilder.Marker parameters = mark(); 2119 2120 myBuilder.disableNewlines(); 2121 advance(); // LPAR 2122 2123 if (!at(RPAR) && !atSet(recoverySet)) { 2124 while (true) { 2125 if (at(COMMA)) { 2126 errorAndAdvance("Expecting a parameter declaration"); 2127 } 2128 else if (at(RPAR)) { 2129 error("Expecting a parameter declaration"); 2130 break; 2131 } 2132 2133 if (isFunctionTypeContents) { 2134 if (!tryParseValueParameter(typeRequired)) { 2135 PsiBuilder.Marker valueParameter = mark(); 2136 parseModifierList(DEFAULT, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER); // lazy, out, ref 2137 parseTypeRef(); 2138 closeDeclarationWithCommentBinders(valueParameter, VALUE_PARAMETER, false); 2139 } 2140 } 2141 else { 2142 parseValueParameter(typeRequired); 2143 } 2144 2145 if (at(COMMA)) { 2146 advance(); // COMMA 2147 } 2148 else { 2149 if (!at(RPAR)) error("Expecting comma or ')'"); 2150 if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break; 2151 } 2152 } 2153 } 2154 2155 expect(RPAR, "Expecting ')'", recoverySet); 2156 myBuilder.restoreNewlinesState(); 2157 2158 parameters.done(VALUE_PARAMETER_LIST); 2159 } 2160 2161 /* 2162 * functionParameter 2163 * : modifiers ("val" | "var")? parameter ("=" element)? 2164 * ; 2165 */ 2166 private boolean tryParseValueParameter(boolean typeRequired) { 2167 return parseValueParameter(true, typeRequired); 2168 } 2169 2170 public void parseValueParameter(boolean typeRequired) { 2171 parseValueParameter(false, typeRequired); 2172 } 2173 2174 private boolean parseValueParameter(boolean rollbackOnFailure, boolean typeRequired) { 2175 PsiBuilder.Marker parameter = mark(); 2176 2177 parseModifierList(DEFAULT, NO_MODIFIER_BEFORE_FOR_VALUE_PARAMETER); 2178 2179 if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { 2180 advance(); // VAR_KEYWORD | VAL_KEYWORD 2181 } 2182 2183 if (!parseFunctionParameterRest(typeRequired) && rollbackOnFailure) { 2184 parameter.rollbackTo(); 2185 return false; 2186 } 2187 2188 closeDeclarationWithCommentBinders(parameter, VALUE_PARAMETER, false); 2189 return true; 2190 } 2191 2192 /* 2193 * functionParameterRest 2194 * : parameter ("=" element)? 2195 * ; 2196 */ 2197 private boolean parseFunctionParameterRest(boolean typeRequired) { 2198 boolean noErrors = true; 2199 2200 // Recovery for the case 'fun foo(Array<String>) {}' 2201 // Recovery for the case 'fun foo(: Int) {}' 2202 if ((at(IDENTIFIER) && lookahead(1) == LT) || at(COLON)) { 2203 error("Parameter name expected"); 2204 if (at(COLON)) { 2205 // We keep noErrors == true so that unnamed parameters starting with ":" are not rolled back during parsing of functional types 2206 advance(); // COLON 2207 } 2208 else { 2209 noErrors = false; 2210 } 2211 parseTypeRef(); 2212 } 2213 else { 2214 expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); 2215 2216 if (at(COLON)) { 2217 advance(); // COLON 2218 parseTypeRef(); 2219 } 2220 else if (typeRequired) { 2221 errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET); 2222 noErrors = false; 2223 } 2224 } 2225 2226 if (at(EQ)) { 2227 advance(); // EQ 2228 myExpressionParsing.parseExpression(); 2229 } 2230 2231 return noErrors; 2232 } 2233 2234 @Override 2235 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) { 2236 return createForTopLevel(builder); 2237 } 2238 2239 /*package*/ static class ModifierDetector implements Consumer<IElementType> { 2240 private boolean enumDetected = false; 2241 private boolean defaultDetected = false; 2242 2243 @Override 2244 public void consume(IElementType item) { 2245 if (item == KtTokens.ENUM_KEYWORD) { 2246 enumDetected = true; 2247 } 2248 else if (item == KtTokens.COMPANION_KEYWORD) { 2249 defaultDetected = true; 2250 } 2251 } 2252 2253 public boolean isEnumDetected() { 2254 return enumDetected; 2255 } 2256 2257 public boolean isDefaultDetected() { 2258 return defaultDetected; 2259 } 2260 } 2261 2262 enum AnnotationParsingMode { 2263 DEFAULT(false, false, true), 2264 FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true, true), 2265 FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true, true), 2266 IN_ANNOTATION_LIST(true, false, true), 2267 NO_ANNOTATIONS(false, false, false); 2268 2269 boolean allowShortAnnotations; 2270 boolean isFileAnnotationParsingMode; 2271 boolean allowAnnotations; 2272 2273 AnnotationParsingMode( 2274 boolean allowShortAnnotations, 2275 boolean isFileAnnotationParsingMode, 2276 boolean allowAnnotations 2277 ) { 2278 this.allowShortAnnotations = allowShortAnnotations; 2279 this.isFileAnnotationParsingMode = isFileAnnotationParsingMode; 2280 this.allowAnnotations = allowAnnotations; 2281 } 2282 } 2283 }