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