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