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