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.google.common.collect.ImmutableMap; 020 import com.intellij.lang.PsiBuilder; 021 import com.intellij.psi.tree.IElementType; 022 import com.intellij.psi.tree.TokenSet; 023 import org.jetbrains.annotations.NotNull; 024 import org.jetbrains.kotlin.KtNodeType; 025 import org.jetbrains.kotlin.KtNodeTypes; 026 import org.jetbrains.kotlin.lexer.KtToken; 027 import org.jetbrains.kotlin.lexer.KtTokens; 028 import org.jetbrains.kotlin.parsing.KotlinParsing.NameParsingMode; 029 030 import java.util.Arrays; 031 import java.util.HashSet; 032 import java.util.Set; 033 034 import static org.jetbrains.kotlin.KtNodeTypes.*; 035 import static org.jetbrains.kotlin.lexer.KtTokens.*; 036 import static org.jetbrains.kotlin.parsing.KotlinParsing.AnnotationParsingMode.DEFAULT; 037 038 public class KotlinExpressionParsing extends AbstractKotlinParsing { 039 private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD); 040 private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT); 041 042 043 private static final ImmutableMap<String, KtToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS); 044 045 private static ImmutableMap<String, KtToken> tokenSetToMap(TokenSet tokens) { 046 ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder(); 047 for (IElementType token : tokens.getTypes()) { 048 builder.put(token.toString(), (KtToken) token); 049 } 050 return builder.build(); 051 } 052 053 private static final TokenSet TYPE_ARGUMENT_LIST_STOPPERS = TokenSet.create( 054 INTEGER_LITERAL, FLOAT_LITERAL, CHARACTER_LITERAL, OPEN_QUOTE, 055 PACKAGE_KEYWORD, AS_KEYWORD, TYPE_ALIAS_KEYWORD, INTERFACE_KEYWORD, CLASS_KEYWORD, THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, 056 FUN_KEYWORD, FOR_KEYWORD, NULL_KEYWORD, 057 TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, 058 CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, 059 WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL, 060 // MUL, 061 PLUS, MINUS, EXCL, DIV, PERC, LTEQ, 062 // TODO GTEQ, foo<bar, baz>=x 063 EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS, 064 SEMICOLON, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, NOT_IN, NOT_IS, 065 COLONCOLON, 066 COLON 067 ); 068 069 /*package*/ static final TokenSet EXPRESSION_FIRST = TokenSet.create( 070 // Prefix 071 MINUS, PLUS, MINUSMINUS, PLUSPLUS, 072 EXCL, EXCLEXCL, // Joining complex tokens makes it necessary to put EXCLEXCL here 073 // Atomic 074 075 COLONCOLON, // callable reference 076 077 LPAR, // parenthesized 078 079 // literal constant 080 TRUE_KEYWORD, FALSE_KEYWORD, 081 OPEN_QUOTE, 082 INTEGER_LITERAL, CHARACTER_LITERAL, FLOAT_LITERAL, 083 NULL_KEYWORD, 084 085 LBRACE, // functionLiteral 086 FUN_KEYWORD, // expression function 087 088 THIS_KEYWORD, // this 089 SUPER_KEYWORD, // super 090 091 IF_KEYWORD, // if 092 WHEN_KEYWORD, // when 093 TRY_KEYWORD, // try 094 OBJECT_KEYWORD, // object 095 096 // jump 097 THROW_KEYWORD, 098 RETURN_KEYWORD, 099 CONTINUE_KEYWORD, 100 BREAK_KEYWORD, 101 102 // loop 103 FOR_KEYWORD, 104 WHILE_KEYWORD, 105 DO_KEYWORD, 106 107 IDENTIFIER, // SimpleName 108 109 PACKAGE_KEYWORD, // for absolute qualified names 110 AT // Just for better recovery and maybe for annotations 111 ); 112 113 private static final TokenSet STATEMENT_FIRST = TokenSet.orSet( 114 EXPRESSION_FIRST, 115 TokenSet.create( 116 // declaration 117 FUN_KEYWORD, 118 VAL_KEYWORD, VAR_KEYWORD, 119 INTERFACE_KEYWORD, 120 CLASS_KEYWORD, 121 TYPE_ALIAS_KEYWORD 122 ), 123 MODIFIER_KEYWORDS 124 ); 125 126 private static final TokenSet STATEMENT_NEW_LINE_QUICK_RECOVERY_SET = 127 TokenSet.orSet( 128 TokenSet.andSet(STATEMENT_FIRST, TokenSet.andNot(KEYWORDS, TokenSet.create(IN_KEYWORD))), 129 TokenSet.create(EOL_OR_SEMICOLON)); 130 131 /*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create( 132 SEMICOLON, ARROW, COMMA, RBRACE, RPAR, RBRACKET 133 ); 134 135 @SuppressWarnings({"UnusedDeclaration"}) 136 public enum Precedence { 137 POSTFIX(PLUSPLUS, MINUSMINUS, EXCLEXCL, 138 DOT, SAFE_ACCESS), // typeArguments? valueArguments : typeArguments : arrayAccess 139 140 PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // annotations 141 142 @Override 143 public void parseHigherPrecedence(KotlinExpressionParsing parser) { 144 throw new IllegalStateException("Don't call this method"); 145 } 146 }, 147 148 AS(AS_KEYWORD, AS_SAFE) { 149 @Override 150 public KtNodeType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) { 151 parser.myJetParsing.parseTypeRef(); 152 return BINARY_WITH_TYPE; 153 } 154 155 @Override 156 public void parseHigherPrecedence(KotlinExpressionParsing parser) { 157 parser.parsePrefixExpression(); 158 } 159 }, 160 161 MULTIPLICATIVE(MUL, DIV, PERC), 162 ADDITIVE(PLUS, MINUS), 163 RANGE(KtTokens.RANGE), 164 SIMPLE_NAME(IDENTIFIER), 165 ELVIS(KtTokens.ELVIS), 166 IN_OR_IS(IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS) { 167 @Override 168 public KtNodeType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) { 169 if (operation == IS_KEYWORD || operation == NOT_IS) { 170 parser.myJetParsing.parseTypeRef(); 171 return IS_EXPRESSION; 172 } 173 174 return super.parseRightHandSide(operation, parser); 175 } 176 }, 177 COMPARISON(LT, GT, LTEQ, GTEQ), 178 EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ), 179 CONJUNCTION(ANDAND), 180 DISJUNCTION(OROR), 181 // ARROW(KtTokens.ARROW), 182 ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ), 183 ; 184 185 static { 186 Precedence[] values = Precedence.values(); 187 for (Precedence precedence : values) { 188 int ordinal = precedence.ordinal(); 189 precedence.higher = ordinal > 0 ? values[ordinal - 1] : null; 190 } 191 } 192 193 private Precedence higher; 194 private final TokenSet operations; 195 196 Precedence(IElementType... operations) { 197 this.operations = TokenSet.create(operations); 198 } 199 200 public void parseHigherPrecedence(KotlinExpressionParsing parser) { 201 assert higher != null; 202 parser.parseBinaryExpression(higher); 203 } 204 205 /** 206 * 207 * @param operation the operation sign (e.g. PLUS or IS) 208 * @param parser the parser object 209 * @return node type of the result 210 */ 211 public KtNodeType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) { 212 parseHigherPrecedence(parser); 213 return BINARY_EXPRESSION; 214 } 215 216 @NotNull 217 public final TokenSet getOperations() { 218 return operations; 219 } 220 } 221 222 public static final TokenSet ALLOW_NEWLINE_OPERATIONS = TokenSet.create( 223 DOT, SAFE_ACCESS, 224 COLON, AS_KEYWORD, AS_SAFE, 225 ELVIS, 226 // Can't allow `is` and `!is` because of when entry conditions: IS_KEYWORD, NOT_IS, 227 ANDAND, 228 OROR 229 ); 230 231 public static final TokenSet ALL_OPERATIONS; 232 233 static { 234 Set<IElementType> operations = new HashSet<IElementType>(); 235 Precedence[] values = Precedence.values(); 236 for (Precedence precedence : values) { 237 operations.addAll(Arrays.asList(precedence.getOperations().getTypes())); 238 } 239 ALL_OPERATIONS = TokenSet.create(operations.toArray(new IElementType[operations.size()])); 240 } 241 242 static { 243 IElementType[] operations = OPERATIONS.getTypes(); 244 Set<IElementType> opSet = new HashSet<IElementType>(Arrays.asList(operations)); 245 IElementType[] usedOperations = ALL_OPERATIONS.getTypes(); 246 Set<IElementType> usedSet = new HashSet<IElementType>(Arrays.asList(usedOperations)); 247 248 if (opSet.size() > usedSet.size()) { 249 opSet.removeAll(usedSet); 250 assert false : opSet; 251 } 252 assert usedSet.size() == opSet.size() : "Either some ops are unused, or something a non-op is used"; 253 254 usedSet.removeAll(opSet); 255 256 assert usedSet.isEmpty() : usedSet.toString(); 257 } 258 259 260 private final KotlinParsing myJetParsing; 261 262 public KotlinExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, KotlinParsing jetParsing) { 263 super(builder); 264 myJetParsing = jetParsing; 265 } 266 267 /* 268 * element 269 * : annotations element 270 * : "(" element ")" // see tupleLiteral 271 * : literalConstant 272 * : functionLiteral 273 * : tupleLiteral 274 * : "null" 275 * : "this" ("<" type ">")? 276 * : expressionWithPrecedences 277 * : if 278 * : try 279 * : "typeof" "(" element ")" 280 * : "new" constructorInvocation 281 * : objectLiteral 282 * : declaration 283 * : jump 284 * : loop 285 * // block is syntactically equivalent to a functionLiteral with no parameters 286 * ; 287 */ 288 public void parseExpression() { 289 if (!atSet(EXPRESSION_FIRST)) { 290 error("Expecting an expression"); 291 return; 292 } 293 parseBinaryExpression(Precedence.ASSIGNMENT); 294 } 295 296 /* 297 * element (operation element)* 298 * 299 * see the precedence table 300 */ 301 private void parseBinaryExpression(Precedence precedence) { 302 // System.out.println(precedence.name() + " at " + myBuilder.getTokenText()); 303 304 PsiBuilder.Marker expression = mark(); 305 306 precedence.parseHigherPrecedence(this); 307 308 while (!interruptedWithNewLine() && atSet(precedence.getOperations())) { 309 IElementType operation = tt(); 310 311 parseOperationReference(); 312 313 KtNodeType resultType = precedence.parseRightHandSide(operation, this); 314 expression.done(resultType); 315 expression = expression.precede(); 316 } 317 318 expression.drop(); 319 } 320 321 /* 322 * label prefixExpression 323 */ 324 private void parseLabeledExpression() { 325 PsiBuilder.Marker expression = mark(); 326 parseLabelDefinition(); 327 parsePrefixExpression(); 328 expression.done(LABELED_EXPRESSION); 329 } 330 331 /* 332 * operation? prefixExpression 333 */ 334 private void parsePrefixExpression() { 335 // System.out.println("pre at " + myBuilder.getTokenText()); 336 337 if (at(AT)) { 338 if (!parseLocalDeclaration()) { 339 PsiBuilder.Marker expression = mark(); 340 myJetParsing.parseAnnotations(DEFAULT); 341 parsePrefixExpression(); 342 expression.done(ANNOTATED_EXPRESSION); 343 } 344 } 345 else { 346 myBuilder.disableJoiningComplexTokens(); 347 if (isAtLabelDefinitionOrMissingIdentifier()) { 348 myBuilder.restoreJoiningComplexTokensState(); 349 parseLabeledExpression(); 350 } 351 else if (atSet(Precedence.PREFIX.getOperations())) { 352 PsiBuilder.Marker expression = mark(); 353 354 parseOperationReference(); 355 356 myBuilder.restoreJoiningComplexTokensState(); 357 358 parsePrefixExpression(); 359 expression.done(PREFIX_EXPRESSION); 360 } 361 else { 362 myBuilder.restoreJoiningComplexTokensState(); 363 parsePostfixExpression(); 364 } 365 } 366 } 367 368 /* 369 * callableReference 370 * : (userType "?"*)? "::" SimpleName typeArguments? 371 * ; 372 */ 373 private boolean parseDoubleColonExpression() { 374 PsiBuilder.Marker expression = mark(); 375 376 if (!at(COLONCOLON)) { 377 PsiBuilder.Marker typeReference = mark(); 378 myJetParsing.parseUserType(); 379 typeReference = myJetParsing.parseNullableTypeSuffix(typeReference); 380 typeReference.done(TYPE_REFERENCE); 381 382 if (!at(COLONCOLON)) { 383 expression.rollbackTo(); 384 return false; 385 } 386 } 387 388 advance(); // COLONCOLON 389 390 if (at(CLASS_KEYWORD)) { 391 advance(); // CLASS_KEYWORD 392 expression.done(CLASS_LITERAL_EXPRESSION); 393 } 394 else { 395 parseSimpleNameExpression(); 396 397 if (at(LT)) { 398 PsiBuilder.Marker typeArgumentList = mark(); 399 if (myJetParsing.tryParseTypeArgumentList(TYPE_ARGUMENT_LIST_STOPPERS)) { 400 typeArgumentList.error("Type arguments are not allowed"); 401 } 402 else { 403 typeArgumentList.rollbackTo(); 404 } 405 } 406 407 expression.done(CALLABLE_REFERENCE_EXPRESSION); 408 } 409 410 return true; 411 } 412 413 /* 414 * postfixUnaryExpression 415 * : atomicExpression postfixUnaryOperation* 416 * : callableReference postfixUnaryOperation* 417 * ; 418 * 419 * postfixUnaryOperation 420 * : "++" : "--" : "!!" 421 * : typeArguments? valueArguments (getEntryPoint? functionLiteral) 422 * : typeArguments (getEntryPoint? functionLiteral) 423 * : arrayAccess 424 * : memberAccessOperation postfixUnaryExpression // TODO: Review 425 * ; 426 */ 427 private void parsePostfixExpression() { 428 PsiBuilder.Marker expression = mark(); 429 430 boolean firstExpressionParsed; 431 boolean doubleColonExpression = parseDoubleColonExpression(); 432 if (!doubleColonExpression) { 433 firstExpressionParsed = parseAtomicExpression(); 434 } 435 else { 436 firstExpressionParsed = true; 437 } 438 439 while (true) { 440 if (interruptedWithNewLine()) { 441 break; 442 } 443 else if (at(LBRACKET)) { 444 parseArrayAccess(); 445 expression.done(ARRAY_ACCESS_EXPRESSION); 446 } 447 else if (!doubleColonExpression && parseCallSuffix()) { 448 expression.done(CALL_EXPRESSION); 449 } 450 else if (at(DOT) || at(SAFE_ACCESS)) { 451 IElementType expressionType = at(DOT) ? DOT_QUALIFIED_EXPRESSION : SAFE_ACCESS_EXPRESSION; 452 advance(); // DOT or SAFE_ACCESS 453 454 if (!firstExpressionParsed) { 455 expression.drop(); 456 expression = mark(); 457 } 458 459 parseCallExpression(); 460 461 if (firstExpressionParsed) { 462 expression.done(expressionType); 463 } 464 else { 465 firstExpressionParsed = true; 466 continue; 467 } 468 } 469 else if (atSet(Precedence.POSTFIX.getOperations())) { 470 parseOperationReference(); 471 expression.done(POSTFIX_EXPRESSION); 472 } 473 else { 474 break; 475 } 476 expression = expression.precede(); 477 } 478 expression.drop(); 479 } 480 481 /* 482 * callSuffix 483 * : typeArguments? valueArguments annotatedLambda 484 * : typeArguments annotatedLambda 485 * ; 486 */ 487 private boolean parseCallSuffix() { 488 if (parseCallWithClosure()) { 489 // do nothing 490 } 491 else if (at(LPAR)) { 492 parseValueArgumentList(); 493 parseCallWithClosure(); 494 } 495 else if (at(LT)) { 496 PsiBuilder.Marker typeArgumentList = mark(); 497 if (myJetParsing.tryParseTypeArgumentList(TYPE_ARGUMENT_LIST_STOPPERS)) { 498 typeArgumentList.done(TYPE_ARGUMENT_LIST); 499 if (!myBuilder.newlineBeforeCurrentToken() && at(LPAR)) parseValueArgumentList(); 500 parseCallWithClosure(); 501 } 502 else { 503 typeArgumentList.rollbackTo(); 504 return false; 505 } 506 } 507 else { 508 return false; 509 } 510 511 return true; 512 } 513 514 /* 515 * atomicExpression typeParameters? valueParameters? functionLiteral* 516 */ 517 private void parseCallExpression() { 518 PsiBuilder.Marker mark = mark(); 519 parseAtomicExpression(); 520 if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) { 521 mark.done(CALL_EXPRESSION); 522 } 523 else { 524 mark.drop(); 525 } 526 } 527 528 private void parseOperationReference() { 529 PsiBuilder.Marker operationReference = mark(); 530 advance(); // operation 531 operationReference.done(OPERATION_REFERENCE); 532 } 533 534 /* 535 * annotatedLambda* 536 */ 537 protected boolean parseCallWithClosure() { 538 boolean success = false; 539 540 while (true) { 541 PsiBuilder.Marker argument = mark(); 542 543 if (!parseAnnotatedLambda(/* preferBlock = */false)) { 544 argument.drop(); 545 break; 546 } 547 548 argument.done(FUNCTION_LITERAL_ARGUMENT); 549 success = true; 550 } 551 552 return success; 553 } 554 555 /* 556 * annotatedLambda 557 * : ("@" annotationEntry)* labelDefinition? functionLiteral 558 */ 559 private boolean parseAnnotatedLambda(boolean preferBlock) { 560 PsiBuilder.Marker annotated = mark(); 561 562 boolean wereAnnotations = myJetParsing.parseAnnotations(DEFAULT); 563 PsiBuilder.Marker labeled = mark(); 564 565 boolean wasLabel = isAtLabelDefinitionOrMissingIdentifier(); 566 if (wasLabel) { 567 parseLabelDefinition(); 568 } 569 570 if (!at(LBRACE)) { 571 annotated.rollbackTo(); 572 return false; 573 } 574 575 parseFunctionLiteral(preferBlock); 576 577 doneOrDrop(labeled, LABELED_EXPRESSION, wasLabel); 578 doneOrDrop(annotated, ANNOTATED_EXPRESSION, wereAnnotations); 579 580 return true; 581 } 582 583 private static void doneOrDrop( 584 @NotNull PsiBuilder.Marker marker, 585 @NotNull IElementType type, 586 boolean condition 587 ) { 588 if (condition) { 589 marker.done(type); 590 } 591 else { 592 marker.drop(); 593 } 594 } 595 596 private boolean isAtLabelDefinitionBeforeLBrace() { 597 if (at(IDENTIFIER)) { 598 if (myBuilder.rawLookup(1) != AT) return false; 599 return lookahead(2) == LBRACE; 600 } 601 602 return at(AT) && lookahead(1) == LBRACE; 603 } 604 605 private boolean isAtLabelDefinitionOrMissingIdentifier() { 606 return (at(IDENTIFIER) && myBuilder.rawLookup(1) == AT) || at(AT); 607 } 608 609 /* 610 * atomicExpression 611 * : "this" label? 612 * : "super" ("<" type ">")? label? 613 * : objectLiteral 614 * : jump 615 * : if 616 * : when 617 * : try 618 * : loop 619 * : literalConstant 620 * : functionLiteral 621 * : declaration 622 * : SimpleName 623 * : "package" // for the root package 624 * ; 625 */ 626 private boolean parseAtomicExpression() { 627 // System.out.println("atom at " + myBuilder.getTokenText()); 628 629 boolean ok = true; 630 631 if (at(LPAR)) { 632 parseParenthesizedExpression(); 633 } 634 else if (at(PACKAGE_KEYWORD)) { 635 parseOneTokenExpression(ROOT_PACKAGE); 636 } 637 else if (at(THIS_KEYWORD)) { 638 parseThisExpression(); 639 } 640 else if (at(SUPER_KEYWORD)) { 641 parseSuperExpression(); 642 } 643 else if (at(OBJECT_KEYWORD)) { 644 parseObjectLiteral(); 645 } 646 else if (at(THROW_KEYWORD)) { 647 parseThrow(); 648 } 649 else if (at(RETURN_KEYWORD)) { 650 parseReturn(); 651 } 652 else if (at(CONTINUE_KEYWORD)) { 653 parseJump(CONTINUE); 654 } 655 else if (at(BREAK_KEYWORD)) { 656 parseJump(BREAK); 657 } 658 else if (at(IF_KEYWORD)) { 659 parseIf(); 660 } 661 else if (at(WHEN_KEYWORD)) { 662 parseWhen(); 663 } 664 else if (at(TRY_KEYWORD)) { 665 parseTry(); 666 } 667 else if (at(FOR_KEYWORD)) { 668 parseFor(); 669 } 670 else if (at(WHILE_KEYWORD)) { 671 parseWhile(); 672 } 673 else if (at(DO_KEYWORD)) { 674 parseDoWhile(); 675 } 676 else if (atSet(CLASS_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, 677 VAR_KEYWORD, TYPE_ALIAS_KEYWORD)) { 678 parseLocalDeclaration(); 679 } 680 else if (at(IDENTIFIER)) { 681 parseSimpleNameExpression(); 682 } 683 else if (at(LBRACE)) { 684 parseFunctionLiteral(); 685 } 686 else if (at(OPEN_QUOTE)) { 687 parseStringTemplate(); 688 } 689 else if (!parseLiteralConstant()) { 690 ok = false; 691 // TODO: better recovery if FIRST(element) did not match 692 errorWithRecovery("Expecting an element", EXPRESSION_FOLLOW); 693 } 694 695 return ok; 696 } 697 698 /* 699 * stringTemplate 700 * : OPEN_QUOTE stringTemplateElement* CLOSING_QUOTE 701 * ; 702 */ 703 private void parseStringTemplate() { 704 assert _at(OPEN_QUOTE); 705 706 PsiBuilder.Marker template = mark(); 707 708 advance(); // OPEN_QUOTE 709 710 while (!eof()) { 711 if (at(CLOSING_QUOTE) || at(DANGLING_NEWLINE)) { 712 break; 713 } 714 parseStringTemplateElement(); 715 } 716 717 if (at(DANGLING_NEWLINE)) { 718 errorAndAdvance("Expecting '\"'"); 719 } 720 else { 721 expect(CLOSING_QUOTE, "Expecting '\"'"); 722 } 723 template.done(STRING_TEMPLATE); 724 } 725 726 /* 727 * stringTemplateElement 728 * : RegularStringPart 729 * : ShortTemplateEntrySTART (SimpleName | "this") 730 * : EscapeSequence 731 * : longTemplate 732 * ; 733 * 734 * longTemplate 735 * : "${" expression "}" 736 * ; 737 */ 738 private void parseStringTemplateElement() { 739 if (at(REGULAR_STRING_PART)) { 740 PsiBuilder.Marker mark = mark(); 741 advance(); // REGULAR_STRING_PART 742 mark.done(LITERAL_STRING_TEMPLATE_ENTRY); 743 } 744 else if (at(ESCAPE_SEQUENCE)) { 745 PsiBuilder.Marker mark = mark(); 746 advance(); // ESCAPE_SEQUENCE 747 mark.done(ESCAPE_STRING_TEMPLATE_ENTRY); 748 } 749 else if (at(SHORT_TEMPLATE_ENTRY_START)) { 750 PsiBuilder.Marker entry = mark(); 751 advance(); // SHORT_TEMPLATE_ENTRY_START 752 753 if (at(THIS_KEYWORD)) { 754 PsiBuilder.Marker thisExpression = mark(); 755 PsiBuilder.Marker reference = mark(); 756 advance(); // THIS_KEYWORD 757 reference.done(REFERENCE_EXPRESSION); 758 thisExpression.done(THIS_EXPRESSION); 759 } 760 else { 761 KtToken keyword = KEYWORD_TEXTS.get(myBuilder.getTokenText()); 762 if (keyword != null) { 763 myBuilder.remapCurrentToken(keyword); 764 errorAndAdvance("Keyword cannot be used as a reference"); 765 } 766 else { 767 PsiBuilder.Marker reference = mark(); 768 expect(IDENTIFIER, "Expecting a name"); 769 reference.done(REFERENCE_EXPRESSION); 770 } 771 } 772 773 entry.done(SHORT_STRING_TEMPLATE_ENTRY); 774 } 775 else if (at(LONG_TEMPLATE_ENTRY_START)) { 776 PsiBuilder.Marker longTemplateEntry = mark(); 777 778 advance(); // LONG_TEMPLATE_ENTRY_START 779 780 parseExpression(); 781 782 expect(LONG_TEMPLATE_ENTRY_END, "Expecting '}'", TokenSet.create(CLOSING_QUOTE, DANGLING_NEWLINE, REGULAR_STRING_PART, ESCAPE_SEQUENCE, SHORT_TEMPLATE_ENTRY_START)); 783 longTemplateEntry.done(LONG_STRING_TEMPLATE_ENTRY); 784 } 785 else { 786 errorAndAdvance("Unexpected token in a string template"); 787 } 788 } 789 790 /* 791 * literalConstant 792 * : "true" | "false" 793 * : stringTemplate 794 * : NoEscapeString 795 * : IntegerLiteral 796 * : LongLiteral 797 * : CharacterLiteral 798 * : FloatLiteral 799 * : "null" 800 * ; 801 */ 802 private boolean parseLiteralConstant() { 803 if (at(TRUE_KEYWORD) || at(FALSE_KEYWORD)) { 804 parseOneTokenExpression(BOOLEAN_CONSTANT); 805 } 806 else if (at(INTEGER_LITERAL)) { 807 parseOneTokenExpression(INTEGER_CONSTANT); 808 } 809 else if (at(CHARACTER_LITERAL)) { 810 parseOneTokenExpression(CHARACTER_CONSTANT); 811 } 812 else if (at(FLOAT_LITERAL)) { 813 parseOneTokenExpression(FLOAT_CONSTANT); 814 } 815 else if (at(NULL_KEYWORD)) { 816 parseOneTokenExpression(NULL); 817 } 818 else { 819 return false; 820 } 821 return true; 822 } 823 824 /* 825 * when 826 * : "when" ("(" (modifiers "val" SimpleName "=")? element ")")? "{" 827 * whenEntry* 828 * "}" 829 * ; 830 */ 831 private void parseWhen() { 832 assert _at(WHEN_KEYWORD); 833 834 PsiBuilder.Marker when = mark(); 835 836 advance(); // WHEN_KEYWORD 837 838 // Parse condition 839 myBuilder.disableNewlines(); 840 if (at(LPAR)) { 841 advanceAt(LPAR); 842 843 PsiBuilder.Marker property = mark(); 844 myJetParsing.parseModifierList(DEFAULT, TokenSet.create(EQ, RPAR)); 845 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) { 846 myJetParsing.parseProperty(true); 847 property.done(PROPERTY); 848 } 849 else { 850 property.rollbackTo(); 851 parseExpression(); 852 } 853 854 expect(RPAR, "Expecting ')'"); 855 } 856 myBuilder.restoreNewlinesState(); 857 858 // Parse when block 859 myBuilder.enableNewlines(); 860 if (expect(LBRACE, "Expecting '{'")) { 861 while (!eof() && !at(RBRACE)) { 862 parseWhenEntry(); 863 } 864 865 expect(RBRACE, "Expecting '}'"); 866 } 867 myBuilder.restoreNewlinesState(); 868 869 when.done(WHEN); 870 } 871 872 /* 873 * whenEntry 874 * // TODO : consider empty after -> 875 * : whenCondition{","} "->" element SEMI 876 * : "else" "->" element SEMI 877 * ; 878 */ 879 private void parseWhenEntry() { 880 PsiBuilder.Marker entry = mark(); 881 882 if (at(ELSE_KEYWORD)) { 883 advance(); // ELSE_KEYWORD 884 885 if (!at(ARROW)) { 886 errorUntil("Expecting '->'", TokenSet.create(ARROW, LBRACE, RBRACE, EOL_OR_SEMICOLON)); 887 } 888 889 if (at(ARROW)) { 890 advance(); // ARROW 891 892 if (atSet(WHEN_CONDITION_RECOVERY_SET)) { 893 error("Expecting an element"); 894 } 895 else { 896 parseExpressionPreferringBlocks(); 897 } 898 } 899 else if (at(LBRACE)) { // no arrow, probably it's simply missing 900 parseExpressionPreferringBlocks(); 901 } 902 else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) { 903 errorAndAdvance("Expecting '->'"); 904 } 905 } 906 else { 907 parseWhenEntryNotElse(); 908 } 909 910 entry.done(WHEN_ENTRY); 911 consumeIf(SEMICOLON); 912 } 913 914 /* 915 * : whenCondition{","} "->" element SEMI 916 */ 917 private void parseWhenEntryNotElse() { 918 while (true) { 919 while (at(COMMA)) errorAndAdvance("Expecting a when-condition"); 920 parseWhenCondition(); 921 if (!at(COMMA)) break; 922 advance(); // COMMA 923 } 924 925 expect(ARROW, "Expecting '->'", WHEN_CONDITION_RECOVERY_SET); 926 if (atSet(WHEN_CONDITION_RECOVERY_SET)) { 927 error("Expecting an element"); 928 } 929 else { 930 parseExpressionPreferringBlocks(); 931 } 932 // SEMI is consumed in parseWhenEntry 933 } 934 935 /* 936 * whenCondition 937 * : expression 938 * : ("in" | "!in") expression 939 * : ("is" | "!is") isRHS 940 * ; 941 */ 942 private void parseWhenCondition() { 943 PsiBuilder.Marker condition = mark(); 944 myBuilder.disableNewlines(); 945 if (at(IN_KEYWORD) || at(NOT_IN)) { 946 PsiBuilder.Marker mark = mark(); 947 advance(); // IN_KEYWORD or NOT_IN 948 mark.done(OPERATION_REFERENCE); 949 950 951 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { 952 error("Expecting an element"); 953 } 954 else { 955 parseExpression(); 956 } 957 condition.done(WHEN_CONDITION_IN_RANGE); 958 } 959 else if (at(IS_KEYWORD) || at(NOT_IS)) { 960 advance(); // IS_KEYWORD or NOT_IS 961 962 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { 963 error("Expecting a type"); 964 } 965 else { 966 myJetParsing.parseTypeRef(); 967 } 968 condition.done(WHEN_CONDITION_IS_PATTERN); 969 } 970 else { 971 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { 972 error("Expecting an expression, is-condition or in-condition"); 973 } 974 else { 975 parseExpression(); 976 } 977 condition.done(WHEN_CONDITION_EXPRESSION); 978 } 979 myBuilder.restoreNewlinesState(); 980 } 981 982 /* 983 * arrayAccess 984 * : "[" element{","} "]" 985 * ; 986 */ 987 private void parseArrayAccess() { 988 assert _at(LBRACKET); 989 990 PsiBuilder.Marker indices = mark(); 991 992 myBuilder.disableNewlines(); 993 advance(); // LBRACKET 994 995 while (true) { 996 if (at(COMMA)) errorAndAdvance("Expecting an index element"); 997 if (at(RBRACKET)) { 998 error("Expecting an index element"); 999 break; 1000 } 1001 parseExpression(); 1002 if (!at(COMMA)) break; 1003 advance(); // COMMA 1004 } 1005 1006 expect(RBRACKET, "Expecting ']'"); 1007 myBuilder.restoreNewlinesState(); 1008 1009 indices.done(INDICES); 1010 } 1011 1012 /* 1013 * SimpleName 1014 */ 1015 public void parseSimpleNameExpression() { 1016 PsiBuilder.Marker simpleName = mark(); 1017 expect(IDENTIFIER, "Expecting an identifier"); 1018 simpleName.done(REFERENCE_EXPRESSION); 1019 } 1020 1021 /* 1022 * modifiers declarationRest 1023 */ 1024 private boolean parseLocalDeclaration() { 1025 PsiBuilder.Marker decl = mark(); 1026 KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector(); 1027 myJetParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY); 1028 1029 IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected()); 1030 1031 if (declType != null) { 1032 // we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below 1033 closeDeclarationWithCommentBinders(decl, declType, 1034 declType != KtNodeTypes.PROPERTY && declType != KtNodeTypes.MULTI_VARIABLE_DECLARATION); 1035 return true; 1036 } 1037 else { 1038 decl.rollbackTo(); 1039 return false; 1040 } 1041 } 1042 1043 /* 1044 * functionLiteral // one can use "it" as a parameter name 1045 * : "{" expressions "}" 1046 * : "{" (modifiers SimpleName){","} "->" statements "}" 1047 * ; 1048 */ 1049 private void parseFunctionLiteral() { 1050 parseFunctionLiteral(/* preferBlock = */false); 1051 } 1052 1053 private void parseFunctionLiteral(boolean preferBlock) { 1054 assert _at(LBRACE); 1055 1056 PsiBuilder.Marker literalExpression = mark(); 1057 1058 PsiBuilder.Marker literal = mark(); 1059 1060 myBuilder.enableNewlines(); 1061 advance(); // LBRACE 1062 1063 boolean paramsFound = false; 1064 1065 if (at(ARROW)) { 1066 // { -> ...} 1067 mark().done(VALUE_PARAMETER_LIST); 1068 advance(); // ARROW 1069 paramsFound = true; 1070 } 1071 else { 1072 if (at(IDENTIFIER) || at(COLON)) { 1073 // Try to parse a simple name list followed by an ARROW 1074 // {a -> ...} 1075 // {a, b -> ...} 1076 PsiBuilder.Marker rollbackMarker = mark(); 1077 IElementType nextToken = lookahead(1); 1078 boolean preferParamsToExpressions = (nextToken == COMMA || nextToken == COLON); 1079 parseFunctionLiteralShorthandParameterList(); 1080 1081 paramsFound = preferParamsToExpressions ? 1082 rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : 1083 rollbackOrDropAt(rollbackMarker, ARROW); 1084 } 1085 } 1086 1087 if (!paramsFound) { 1088 if (preferBlock) { 1089 literal.drop(); 1090 parseStatements(); 1091 expect(RBRACE, "Expecting '}'"); 1092 literalExpression.done(BLOCK); 1093 myBuilder.restoreNewlinesState(); 1094 1095 return; 1096 } 1097 } 1098 1099 PsiBuilder.Marker body = mark(); 1100 parseStatements(); 1101 body.done(BLOCK); 1102 1103 expect(RBRACE, "Expecting '}'"); 1104 myBuilder.restoreNewlinesState(); 1105 1106 literal.done(FUNCTION_LITERAL); 1107 literalExpression.done(FUNCTION_LITERAL_EXPRESSION); 1108 } 1109 1110 private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) { 1111 if (at(dropAt)) { 1112 advance(); // dropAt 1113 rollbackMarker.drop(); 1114 return true; 1115 } 1116 rollbackMarker.rollbackTo(); 1117 return false; 1118 } 1119 1120 private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker, 1121 KtToken expected, String expectMessage, 1122 IElementType validForDrop) { 1123 if (at(expected)) { 1124 advance(); // dropAt 1125 rollbackMarker.drop(); 1126 return true; 1127 } 1128 else if (at(validForDrop)) { 1129 rollbackMarker.drop(); 1130 expect(expected, expectMessage); 1131 return true; 1132 } 1133 1134 rollbackMarker.rollbackTo(); 1135 return false; 1136 } 1137 1138 1139 /* 1140 * SimpleName{,} 1141 */ 1142 private void parseFunctionLiteralShorthandParameterList() { 1143 PsiBuilder.Marker parameterList = mark(); 1144 1145 while (!eof()) { 1146 PsiBuilder.Marker parameter = mark(); 1147 1148 // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos))); 1149 // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false); 1150 1151 if (at(COLON)) { 1152 error("Expecting parameter name"); 1153 } 1154 else { 1155 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); 1156 } 1157 1158 if (at(COLON)) { 1159 advance(); // COLON 1160 myJetParsing.parseTypeRef(TokenSet.create(ARROW, COMMA)); 1161 } 1162 parameter.done(VALUE_PARAMETER); 1163 1164 if (at(ARROW)) { 1165 break; 1166 } 1167 else if (at(COMMA)) { 1168 advance(); // COMMA 1169 } 1170 else { 1171 error("Expecting '->' or ','"); 1172 break; 1173 } 1174 } 1175 1176 parameterList.done(VALUE_PARAMETER_LIST); 1177 } 1178 1179 /* 1180 * expressions 1181 * : SEMI* statement{SEMI+} SEMI* 1182 */ 1183 public void parseStatements() { 1184 parseStatements(false); 1185 } 1186 1187 /* 1188 * expressions 1189 * : SEMI* statement{SEMI+} SEMI* 1190 */ 1191 public void parseStatements(boolean isScriptTopLevel) { 1192 while (at(SEMICOLON)) advance(); // SEMICOLON 1193 while (!eof() && !at(RBRACE)) { 1194 if (!atSet(STATEMENT_FIRST)) { 1195 errorAndAdvance("Expecting an element"); 1196 } 1197 if (atSet(STATEMENT_FIRST)) { 1198 parseStatement(isScriptTopLevel); 1199 } 1200 if (at(SEMICOLON)) { 1201 while (at(SEMICOLON)) advance(); // SEMICOLON 1202 } 1203 else if (at(RBRACE)) { 1204 break; 1205 } 1206 else if (!myBuilder.newlineBeforeCurrentToken()) { 1207 String severalStatementsError = "Unexpected tokens (use ';' to separate expressions on the same line)"; 1208 1209 if (atSet(STATEMENT_NEW_LINE_QUICK_RECOVERY_SET)) { 1210 error(severalStatementsError); 1211 } 1212 else { 1213 errorUntil(severalStatementsError, TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE)); 1214 } 1215 } 1216 } 1217 } 1218 1219 /* 1220 * statement 1221 * : expression 1222 * : declaration 1223 * ; 1224 */ 1225 private void parseStatement(boolean isScriptTopLevel) { 1226 if (!parseLocalDeclaration()) { 1227 if (!atSet(EXPRESSION_FIRST)) { 1228 errorAndAdvance("Expecting a statement"); 1229 } 1230 else if (isScriptTopLevel){ 1231 PsiBuilder.Marker scriptInitializer = mark(); 1232 parseExpression(); 1233 scriptInitializer.done(SCRIPT_INITIALIZER); 1234 } 1235 else { 1236 parseExpression(); 1237 } 1238 } 1239 } 1240 1241 /* 1242 * declaration 1243 * : function 1244 * : property 1245 * : extension 1246 * : class 1247 * : typeAlias 1248 * : object 1249 * ; 1250 */ 1251 private IElementType parseLocalDeclarationRest(boolean isEnum) { 1252 IElementType keywordToken = tt(); 1253 IElementType declType = null; 1254 if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) { 1255 declType = myJetParsing.parseClass(isEnum); 1256 } 1257 else if (keywordToken == FUN_KEYWORD) { 1258 declType = myJetParsing.parseFunction(); 1259 } 1260 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { 1261 declType = myJetParsing.parseProperty(true); 1262 } 1263 else if (keywordToken == TYPE_ALIAS_KEYWORD) { 1264 declType = myJetParsing.parseTypeAlias(); 1265 } 1266 else if (keywordToken == OBJECT_KEYWORD) { 1267 // Object expression may appear at the statement position: should parse it 1268 // as expression instead of object declaration 1269 // sample: 1270 // { 1271 // object : Thread() { 1272 // } 1273 // } 1274 IElementType lookahead = lookahead(1); 1275 if (lookahead == COLON || lookahead == LBRACE) { 1276 return null; 1277 } 1278 1279 myJetParsing.parseObject(NameParsingMode.REQUIRED, true); 1280 declType = OBJECT_DECLARATION; 1281 } 1282 return declType; 1283 } 1284 1285 /* 1286 * doWhile 1287 * : "do" element "while" "(" element ")" 1288 * ; 1289 */ 1290 private void parseDoWhile() { 1291 assert _at(DO_KEYWORD); 1292 1293 PsiBuilder.Marker loop = mark(); 1294 1295 advance(); // DO_KEYWORD 1296 1297 if (!at(WHILE_KEYWORD)) { 1298 parseControlStructureBody(); 1299 } 1300 1301 if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) { 1302 parseCondition(); 1303 } 1304 1305 loop.done(DO_WHILE); 1306 } 1307 1308 /* 1309 * while 1310 * : "while" "(" element ")" element 1311 * ; 1312 */ 1313 private void parseWhile() { 1314 assert _at(WHILE_KEYWORD); 1315 1316 PsiBuilder.Marker loop = mark(); 1317 1318 advance(); // WHILE_KEYWORD 1319 1320 parseCondition(); 1321 1322 parseControlStructureBody(); 1323 1324 loop.done(WHILE); 1325 } 1326 1327 /* 1328 * for 1329 * : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression 1330 * ; 1331 * 1332 * TODO: empty loop body (at the end of the block)? 1333 */ 1334 private void parseFor() { 1335 assert _at(FOR_KEYWORD); 1336 1337 PsiBuilder.Marker loop = mark(); 1338 1339 advance(); // FOR_KEYWORD 1340 1341 if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) { 1342 myBuilder.disableNewlines(); 1343 1344 if (!at(RPAR)) { 1345 PsiBuilder.Marker parameter = mark(); 1346 1347 if (!at(IN_KEYWORD)) { 1348 myJetParsing.parseModifierList(DEFAULT, TokenSet.create(IN_KEYWORD, RPAR, COLON)); 1349 } 1350 1351 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD 1352 1353 if (at(LPAR)) { 1354 myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE)); 1355 parameter.done(MULTI_VARIABLE_DECLARATION); 1356 } 1357 else { 1358 expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD)); 1359 1360 if (at(COLON)) { 1361 advance(); // COLON 1362 myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD)); 1363 } 1364 parameter.done(VALUE_PARAMETER); 1365 } 1366 1367 if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) { 1368 PsiBuilder.Marker range = mark(); 1369 parseExpression(); 1370 range.done(LOOP_RANGE); 1371 } 1372 } 1373 else { 1374 error("Expecting a variable name"); 1375 } 1376 1377 expectNoAdvance(RPAR, "Expecting ')'"); 1378 myBuilder.restoreNewlinesState(); 1379 } 1380 1381 parseControlStructureBody(); 1382 1383 loop.done(FOR); 1384 } 1385 1386 /** 1387 * If it has no ->, it's a block, otherwise a function literal 1388 */ 1389 private void parseExpressionPreferringBlocks() { 1390 if (!parseAnnotatedLambda(/* preferBlock = */true)) { 1391 parseExpression(); 1392 } 1393 } 1394 1395 /* 1396 * element 1397 */ 1398 private void parseControlStructureBody() { 1399 PsiBuilder.Marker body = mark(); 1400 if (!at(SEMICOLON)) { 1401 parseExpressionPreferringBlocks(); 1402 } 1403 body.done(BODY); 1404 } 1405 1406 /* 1407 * try 1408 * : "try" block catchBlock* finallyBlock? 1409 * ; 1410 * catchBlock 1411 * : "catch" "(" annotations SimpleName ":" userType ")" block 1412 * ; 1413 * 1414 * finallyBlock 1415 * : "finally" block 1416 * ; 1417 */ 1418 private void parseTry() { 1419 assert _at(TRY_KEYWORD); 1420 1421 PsiBuilder.Marker tryExpression = mark(); 1422 1423 advance(); // TRY_KEYWORD 1424 1425 myJetParsing.parseBlock(); 1426 1427 boolean catchOrFinally = false; 1428 while (at(CATCH_KEYWORD)) { 1429 catchOrFinally = true; 1430 PsiBuilder.Marker catchBlock = mark(); 1431 advance(); // CATCH_KEYWORD 1432 1433 TokenSet recoverySet = TokenSet.create(LBRACE, RBRACE, FINALLY_KEYWORD, CATCH_KEYWORD); 1434 if (atSet(recoverySet)) { 1435 error("Expecting exception variable declaration"); 1436 } 1437 else { 1438 PsiBuilder.Marker parameters = mark(); 1439 expect(LPAR, "Expecting '('", recoverySet); 1440 if (!atSet(recoverySet)) { 1441 myJetParsing.parseValueParameter(/*typeRequired = */ true); 1442 expect(RPAR, "Expecting ')'", recoverySet); 1443 } 1444 else { 1445 error("Expecting exception variable declaration"); 1446 } 1447 parameters.done(VALUE_PARAMETER_LIST); 1448 } 1449 1450 if (at(LBRACE)) { 1451 myJetParsing.parseBlock(); 1452 } 1453 else { 1454 error("Expecting a block: { ... }"); 1455 } 1456 catchBlock.done(CATCH); 1457 } 1458 1459 if (at(FINALLY_KEYWORD)) { 1460 catchOrFinally = true; 1461 PsiBuilder.Marker finallyBlock = mark(); 1462 1463 advance(); // FINALLY_KEYWORD 1464 1465 myJetParsing.parseBlock(); 1466 1467 finallyBlock.done(FINALLY); 1468 } 1469 1470 if (!catchOrFinally) { 1471 error("Expecting 'catch' or 'finally'"); 1472 } 1473 1474 tryExpression.done(TRY); 1475 } 1476 1477 /* 1478 * if 1479 * : "if" "(" element ")" element SEMI? ("else" element)? 1480 * ; 1481 */ 1482 private void parseIf() { 1483 assert _at(IF_KEYWORD); 1484 1485 PsiBuilder.Marker marker = mark(); 1486 1487 advance(); //IF_KEYWORD 1488 1489 parseCondition(); 1490 1491 PsiBuilder.Marker thenBranch = mark(); 1492 if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) { 1493 parseExpressionPreferringBlocks(); 1494 } 1495 if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) { 1496 advance(); // SEMICOLON 1497 } 1498 thenBranch.done(THEN); 1499 1500 // lookahead for arrow is needed to prevent capturing of whenEntry like "else -> " 1501 if (at(ELSE_KEYWORD) && lookahead(1) != ARROW) { 1502 advance(); // ELSE_KEYWORD 1503 1504 PsiBuilder.Marker elseBranch = mark(); 1505 if (!at(SEMICOLON)) { 1506 parseExpressionPreferringBlocks(); 1507 } 1508 elseBranch.done(ELSE); 1509 } 1510 1511 marker.done(IF); 1512 } 1513 1514 /* 1515 * "(" element ")" 1516 */ 1517 private void parseCondition() { 1518 myBuilder.disableNewlines(); 1519 1520 if (expect(LPAR, "Expecting a condition in parentheses '(...)'", EXPRESSION_FIRST)) { 1521 PsiBuilder.Marker condition = mark(); 1522 parseExpression(); 1523 condition.done(CONDITION); 1524 expect(RPAR, "Expecting ')"); 1525 } 1526 1527 myBuilder.restoreNewlinesState(); 1528 } 1529 1530 /* 1531 * : "continue" getEntryPoint? 1532 * : "break" getEntryPoint? 1533 */ 1534 private void parseJump(KtNodeType type) { 1535 assert _at(BREAK_KEYWORD) || _at(CONTINUE_KEYWORD); 1536 1537 PsiBuilder.Marker marker = mark(); 1538 1539 advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD 1540 1541 parseLabelReferenceWithNoWhitespace(); 1542 1543 marker.done(type); 1544 } 1545 1546 /* 1547 * "return" getEntryPoint? element? 1548 */ 1549 private void parseReturn() { 1550 assert _at(RETURN_KEYWORD); 1551 1552 PsiBuilder.Marker returnExpression = mark(); 1553 1554 advance(); // RETURN_KEYWORD 1555 1556 parseLabelReferenceWithNoWhitespace(); 1557 1558 if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression(); 1559 1560 returnExpression.done(RETURN); 1561 } 1562 1563 /* 1564 * labelReference? 1565 */ 1566 private void parseLabelReferenceWithNoWhitespace() { 1567 if (at(AT) && !myBuilder.newlineBeforeCurrentToken()) { 1568 if (WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) { 1569 error("There should be no space or comments before '@' in label reference"); 1570 } 1571 parseLabelReference(); 1572 } 1573 } 1574 1575 /* 1576 * IDENTIFIER "@" 1577 */ 1578 private void parseLabelDefinition() { 1579 if (at(AT)) { 1580 // recovery for empty label identifier 1581 errorAndAdvance("Label must be named"); // AT 1582 return; 1583 } 1584 1585 PsiBuilder.Marker labelWrap = mark(); 1586 PsiBuilder.Marker mark = mark(); 1587 1588 assert _at(IDENTIFIER) && myBuilder.rawLookup(1) == AT : "Callers must check that current token is IDENTIFIER followed with '@'"; 1589 1590 advance(); // IDENTIFIER 1591 advance(); // AT 1592 1593 mark.done(LABEL); 1594 1595 labelWrap.done(LABEL_QUALIFIER); 1596 } 1597 1598 /* 1599 * "@" IDENTIFIER 1600 */ 1601 private void parseLabelReference() { 1602 assert _at(AT); 1603 1604 PsiBuilder.Marker labelWrap = mark(); 1605 1606 PsiBuilder.Marker mark = mark(); 1607 1608 if (myBuilder.rawLookup(1) != IDENTIFIER) { 1609 errorAndAdvance("Label must be named"); // AT 1610 labelWrap.drop(); 1611 mark.drop(); 1612 return; 1613 } 1614 1615 advance(); // AT 1616 advance(); // IDENTIFIER 1617 1618 mark.done(LABEL); 1619 1620 labelWrap.done(LABEL_QUALIFIER); 1621 } 1622 1623 /* 1624 * : "throw" element 1625 */ 1626 private void parseThrow() { 1627 assert _at(THROW_KEYWORD); 1628 1629 PsiBuilder.Marker marker = mark(); 1630 1631 advance(); // THROW_KEYWORD 1632 1633 parseExpression(); 1634 1635 marker.done(THROW); 1636 } 1637 1638 /* 1639 * "(" expression ")" 1640 */ 1641 private void parseParenthesizedExpression() { 1642 assert _at(LPAR); 1643 1644 PsiBuilder.Marker mark = mark(); 1645 1646 myBuilder.disableNewlines(); 1647 advance(); // LPAR 1648 if (at(RPAR)) { 1649 error("Expecting an expression"); 1650 } 1651 else { 1652 parseExpression(); 1653 } 1654 1655 expect(RPAR, "Expecting ')'"); 1656 myBuilder.restoreNewlinesState(); 1657 1658 mark.done(PARENTHESIZED); 1659 } 1660 1661 /* 1662 * "this" label? 1663 */ 1664 private void parseThisExpression() { 1665 assert _at(THIS_KEYWORD); 1666 PsiBuilder.Marker mark = mark(); 1667 1668 PsiBuilder.Marker thisReference = mark(); 1669 advance(); // THIS_KEYWORD 1670 thisReference.done(REFERENCE_EXPRESSION); 1671 1672 parseLabelReferenceWithNoWhitespace(); 1673 1674 mark.done(THIS_EXPRESSION); 1675 } 1676 1677 /* 1678 * "this" ("<" type ">")? label? 1679 */ 1680 private void parseSuperExpression() { 1681 assert _at(SUPER_KEYWORD); 1682 PsiBuilder.Marker mark = mark(); 1683 1684 PsiBuilder.Marker superReference = mark(); 1685 advance(); // SUPER_KEYWORD 1686 superReference.done(REFERENCE_EXPRESSION); 1687 1688 if (at(LT)) { 1689 // This may be "super < foo" or "super<foo>", thus the backtracking 1690 PsiBuilder.Marker supertype = mark(); 1691 1692 myBuilder.disableNewlines(); 1693 advance(); // LT 1694 1695 myJetParsing.parseTypeRef(); 1696 1697 if (at(GT)) { 1698 advance(); // GT 1699 supertype.drop(); 1700 } 1701 else { 1702 supertype.rollbackTo(); 1703 } 1704 myBuilder.restoreNewlinesState(); 1705 } 1706 parseLabelReferenceWithNoWhitespace(); 1707 1708 mark.done(SUPER_EXPRESSION); 1709 } 1710 1711 /* 1712 * valueArguments 1713 * : "(" (SimpleName "=")? "*"? element{","} ")" 1714 * ; 1715 */ 1716 public void parseValueArgumentList() { 1717 PsiBuilder.Marker list = mark(); 1718 1719 myBuilder.disableNewlines(); 1720 1721 if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) { 1722 if (!at(RPAR)) { 1723 while (true) { 1724 while (at(COMMA)) errorAndAdvance("Expecting an argument"); 1725 parseValueArgument(); 1726 if (at(COLON) && lookahead(1) == IDENTIFIER) { 1727 errorAndAdvance("Unexpected type specification", 2); 1728 } 1729 if (!at(COMMA)) break; 1730 advance(); // COMMA 1731 if (at(RPAR)) { 1732 error("Expecting an argument"); 1733 break; 1734 } 1735 } 1736 } 1737 1738 expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW); 1739 } 1740 1741 myBuilder.restoreNewlinesState(); 1742 1743 list.done(VALUE_ARGUMENT_LIST); 1744 } 1745 1746 /* 1747 * (SimpleName "=")? "*"? element 1748 */ 1749 private void parseValueArgument() { 1750 PsiBuilder.Marker argument = mark(); 1751 if (at(IDENTIFIER) && lookahead(1) == EQ) { 1752 PsiBuilder.Marker argName = mark(); 1753 PsiBuilder.Marker reference = mark(); 1754 advance(); // IDENTIFIER 1755 reference.done(REFERENCE_EXPRESSION); 1756 argName.done(VALUE_ARGUMENT_NAME); 1757 advance(); // EQ 1758 } 1759 if (at(MUL)) { 1760 advance(); // MUL 1761 } 1762 parseExpression(); 1763 argument.done(VALUE_ARGUMENT); 1764 } 1765 1766 /* 1767 * "object" (":" delegationSpecifier{","})? classBody // Cannot make class body optional: foo(object : F, A) 1768 */ 1769 public void parseObjectLiteral() { 1770 PsiBuilder.Marker literal = mark(); 1771 PsiBuilder.Marker declaration = mark(); 1772 myJetParsing.parseObject(NameParsingMode.PROHIBITED, false); // Body is not optional because of foo(object : A, B) 1773 declaration.done(OBJECT_DECLARATION); 1774 literal.done(OBJECT_LITERAL); 1775 } 1776 1777 private void parseOneTokenExpression(KtNodeType type) { 1778 PsiBuilder.Marker mark = mark(); 1779 advance(); 1780 mark.done(type); 1781 } 1782 1783 @Override 1784 protected KotlinParsing create(SemanticWhitespaceAwarePsiBuilder builder) { 1785 return myJetParsing.create(builder); 1786 } 1787 1788 private boolean interruptedWithNewLine() { 1789 return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken(); 1790 } 1791 }