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