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