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