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