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(LAMBDA_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 * ;
624 */
625 private boolean parseAtomicExpression() {
626 // System.out.println("atom at " + myBuilder.getTokenText());
627
628 boolean ok = true;
629
630 if (at(LPAR)) {
631 parseParenthesizedExpression();
632 }
633 else if (at(THIS_KEYWORD)) {
634 parseThisExpression();
635 }
636 else if (at(SUPER_KEYWORD)) {
637 parseSuperExpression();
638 }
639 else if (at(OBJECT_KEYWORD)) {
640 parseObjectLiteral();
641 }
642 else if (at(THROW_KEYWORD)) {
643 parseThrow();
644 }
645 else if (at(RETURN_KEYWORD)) {
646 parseReturn();
647 }
648 else if (at(CONTINUE_KEYWORD)) {
649 parseJump(CONTINUE);
650 }
651 else if (at(BREAK_KEYWORD)) {
652 parseJump(BREAK);
653 }
654 else if (at(IF_KEYWORD)) {
655 parseIf();
656 }
657 else if (at(WHEN_KEYWORD)) {
658 parseWhen();
659 }
660 else if (at(TRY_KEYWORD)) {
661 parseTry();
662 }
663 else if (at(FOR_KEYWORD)) {
664 parseFor();
665 }
666 else if (at(WHILE_KEYWORD)) {
667 parseWhile();
668 }
669 else if (at(DO_KEYWORD)) {
670 parseDoWhile();
671 }
672 else if (atSet(CLASS_KEYWORD, FUN_KEYWORD, VAL_KEYWORD,
673 VAR_KEYWORD, TYPE_ALIAS_KEYWORD)) {
674 parseLocalDeclaration();
675 }
676 else if (at(IDENTIFIER)) {
677 parseSimpleNameExpression();
678 }
679 else if (at(LBRACE)) {
680 parseFunctionLiteral();
681 }
682 else if (at(OPEN_QUOTE)) {
683 parseStringTemplate();
684 }
685 else if (!parseLiteralConstant()) {
686 ok = false;
687 // TODO: better recovery if FIRST(element) did not match
688 errorWithRecovery("Expecting an element", EXPRESSION_FOLLOW);
689 }
690
691 return ok;
692 }
693
694 /*
695 * stringTemplate
696 * : OPEN_QUOTE stringTemplateElement* CLOSING_QUOTE
697 * ;
698 */
699 private void parseStringTemplate() {
700 assert _at(OPEN_QUOTE);
701
702 PsiBuilder.Marker template = mark();
703
704 advance(); // OPEN_QUOTE
705
706 while (!eof()) {
707 if (at(CLOSING_QUOTE) || at(DANGLING_NEWLINE)) {
708 break;
709 }
710 parseStringTemplateElement();
711 }
712
713 if (at(DANGLING_NEWLINE)) {
714 errorAndAdvance("Expecting '\"'");
715 }
716 else {
717 expect(CLOSING_QUOTE, "Expecting '\"'");
718 }
719 template.done(STRING_TEMPLATE);
720 }
721
722 /*
723 * stringTemplateElement
724 * : RegularStringPart
725 * : ShortTemplateEntrySTART (SimpleName | "this")
726 * : EscapeSequence
727 * : longTemplate
728 * ;
729 *
730 * longTemplate
731 * : "${" expression "}"
732 * ;
733 */
734 private void parseStringTemplateElement() {
735 if (at(REGULAR_STRING_PART)) {
736 PsiBuilder.Marker mark = mark();
737 advance(); // REGULAR_STRING_PART
738 mark.done(LITERAL_STRING_TEMPLATE_ENTRY);
739 }
740 else if (at(ESCAPE_SEQUENCE)) {
741 PsiBuilder.Marker mark = mark();
742 advance(); // ESCAPE_SEQUENCE
743 mark.done(ESCAPE_STRING_TEMPLATE_ENTRY);
744 }
745 else if (at(SHORT_TEMPLATE_ENTRY_START)) {
746 PsiBuilder.Marker entry = mark();
747 advance(); // SHORT_TEMPLATE_ENTRY_START
748
749 if (at(THIS_KEYWORD)) {
750 PsiBuilder.Marker thisExpression = mark();
751 PsiBuilder.Marker reference = mark();
752 advance(); // THIS_KEYWORD
753 reference.done(REFERENCE_EXPRESSION);
754 thisExpression.done(THIS_EXPRESSION);
755 }
756 else {
757 KtToken keyword = KEYWORD_TEXTS.get(myBuilder.getTokenText());
758 if (keyword != null) {
759 myBuilder.remapCurrentToken(keyword);
760 errorAndAdvance("Keyword cannot be used as a reference");
761 }
762 else {
763 PsiBuilder.Marker reference = mark();
764 expect(IDENTIFIER, "Expecting a name");
765 reference.done(REFERENCE_EXPRESSION);
766 }
767 }
768
769 entry.done(SHORT_STRING_TEMPLATE_ENTRY);
770 }
771 else if (at(LONG_TEMPLATE_ENTRY_START)) {
772 PsiBuilder.Marker longTemplateEntry = mark();
773
774 advance(); // LONG_TEMPLATE_ENTRY_START
775
776 parseExpression();
777
778 expect(LONG_TEMPLATE_ENTRY_END, "Expecting '}'", TokenSet.create(CLOSING_QUOTE, DANGLING_NEWLINE, REGULAR_STRING_PART, ESCAPE_SEQUENCE, SHORT_TEMPLATE_ENTRY_START));
779 longTemplateEntry.done(LONG_STRING_TEMPLATE_ENTRY);
780 }
781 else {
782 errorAndAdvance("Unexpected token in a string template");
783 }
784 }
785
786 /*
787 * literalConstant
788 * : "true" | "false"
789 * : stringTemplate
790 * : NoEscapeString
791 * : IntegerLiteral
792 * : LongLiteral
793 * : CharacterLiteral
794 * : FloatLiteral
795 * : "null"
796 * ;
797 */
798 private boolean parseLiteralConstant() {
799 if (at(TRUE_KEYWORD) || at(FALSE_KEYWORD)) {
800 parseOneTokenExpression(BOOLEAN_CONSTANT);
801 }
802 else if (at(INTEGER_LITERAL)) {
803 parseOneTokenExpression(INTEGER_CONSTANT);
804 }
805 else if (at(CHARACTER_LITERAL)) {
806 parseOneTokenExpression(CHARACTER_CONSTANT);
807 }
808 else if (at(FLOAT_LITERAL)) {
809 parseOneTokenExpression(FLOAT_CONSTANT);
810 }
811 else if (at(NULL_KEYWORD)) {
812 parseOneTokenExpression(NULL);
813 }
814 else {
815 return false;
816 }
817 return true;
818 }
819
820 /*
821 * when
822 * : "when" ("(" (modifiers "val" SimpleName "=")? element ")")? "{"
823 * whenEntry*
824 * "}"
825 * ;
826 */
827 private void parseWhen() {
828 assert _at(WHEN_KEYWORD);
829
830 PsiBuilder.Marker when = mark();
831
832 advance(); // WHEN_KEYWORD
833
834 // Parse condition
835 myBuilder.disableNewlines();
836 if (at(LPAR)) {
837 advanceAt(LPAR);
838
839 PsiBuilder.Marker property = mark();
840 myJetParsing.parseModifierList(DEFAULT, TokenSet.create(EQ, RPAR));
841 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
842 myJetParsing.parseProperty(true);
843 property.done(PROPERTY);
844 }
845 else {
846 property.rollbackTo();
847 parseExpression();
848 }
849
850 expect(RPAR, "Expecting ')'");
851 }
852 myBuilder.restoreNewlinesState();
853
854 // Parse when block
855 myBuilder.enableNewlines();
856 if (expect(LBRACE, "Expecting '{'")) {
857 while (!eof() && !at(RBRACE)) {
858 parseWhenEntry();
859 }
860
861 expect(RBRACE, "Expecting '}'");
862 }
863 myBuilder.restoreNewlinesState();
864
865 when.done(WHEN);
866 }
867
868 /*
869 * whenEntry
870 * // TODO : consider empty after ->
871 * : whenCondition{","} "->" element SEMI
872 * : "else" "->" element SEMI
873 * ;
874 */
875 private void parseWhenEntry() {
876 PsiBuilder.Marker entry = mark();
877
878 if (at(ELSE_KEYWORD)) {
879 advance(); // ELSE_KEYWORD
880
881 if (!at(ARROW)) {
882 errorUntil("Expecting '->'", TokenSet.create(ARROW, LBRACE, RBRACE, EOL_OR_SEMICOLON));
883 }
884
885 if (at(ARROW)) {
886 advance(); // ARROW
887
888 if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
889 error("Expecting an element");
890 }
891 else {
892 parseExpressionPreferringBlocks();
893 }
894 }
895 else if (at(LBRACE)) { // no arrow, probably it's simply missing
896 parseExpressionPreferringBlocks();
897 }
898 else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) {
899 errorAndAdvance("Expecting '->'");
900 }
901 }
902 else {
903 parseWhenEntryNotElse();
904 }
905
906 entry.done(WHEN_ENTRY);
907 consumeIf(SEMICOLON);
908 }
909
910 /*
911 * : whenCondition{","} "->" element SEMI
912 */
913 private void parseWhenEntryNotElse() {
914 while (true) {
915 while (at(COMMA)) errorAndAdvance("Expecting a when-condition");
916 parseWhenCondition();
917 if (!at(COMMA)) break;
918 advance(); // COMMA
919 }
920
921 expect(ARROW, "Expecting '->'", WHEN_CONDITION_RECOVERY_SET);
922 if (atSet(WHEN_CONDITION_RECOVERY_SET)) {
923 error("Expecting an element");
924 }
925 else {
926 parseExpressionPreferringBlocks();
927 }
928 // SEMI is consumed in parseWhenEntry
929 }
930
931 /*
932 * whenCondition
933 * : expression
934 * : ("in" | "!in") expression
935 * : ("is" | "!is") isRHS
936 * ;
937 */
938 private void parseWhenCondition() {
939 PsiBuilder.Marker condition = mark();
940 myBuilder.disableNewlines();
941 if (at(IN_KEYWORD) || at(NOT_IN)) {
942 PsiBuilder.Marker mark = mark();
943 advance(); // IN_KEYWORD or NOT_IN
944 mark.done(OPERATION_REFERENCE);
945
946
947 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
948 error("Expecting an element");
949 }
950 else {
951 parseExpression();
952 }
953 condition.done(WHEN_CONDITION_IN_RANGE);
954 }
955 else if (at(IS_KEYWORD) || at(NOT_IS)) {
956 advance(); // IS_KEYWORD or NOT_IS
957
958 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
959 error("Expecting a type");
960 }
961 else {
962 myJetParsing.parseTypeRef();
963 }
964 condition.done(WHEN_CONDITION_IS_PATTERN);
965 }
966 else {
967 if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
968 error("Expecting an expression, is-condition or in-condition");
969 }
970 else {
971 parseExpression();
972 }
973 condition.done(WHEN_CONDITION_EXPRESSION);
974 }
975 myBuilder.restoreNewlinesState();
976 }
977
978 /*
979 * arrayAccess
980 * : "[" element{","} "]"
981 * ;
982 */
983 private void parseArrayAccess() {
984 assert _at(LBRACKET);
985
986 PsiBuilder.Marker indices = mark();
987
988 myBuilder.disableNewlines();
989 advance(); // LBRACKET
990
991 while (true) {
992 if (at(COMMA)) errorAndAdvance("Expecting an index element");
993 if (at(RBRACKET)) {
994 error("Expecting an index element");
995 break;
996 }
997 parseExpression();
998 if (!at(COMMA)) break;
999 advance(); // COMMA
1000 }
1001
1002 expect(RBRACKET, "Expecting ']'");
1003 myBuilder.restoreNewlinesState();
1004
1005 indices.done(INDICES);
1006 }
1007
1008 /*
1009 * SimpleName
1010 */
1011 public void parseSimpleNameExpression() {
1012 PsiBuilder.Marker simpleName = mark();
1013 expect(IDENTIFIER, "Expecting an identifier");
1014 simpleName.done(REFERENCE_EXPRESSION);
1015 }
1016
1017 /*
1018 * modifiers declarationRest
1019 */
1020 private boolean parseLocalDeclaration() {
1021 PsiBuilder.Marker decl = mark();
1022 KotlinParsing.ModifierDetector detector = new KotlinParsing.ModifierDetector();
1023 myJetParsing.parseModifierList(detector, DEFAULT, TokenSet.EMPTY);
1024
1025 IElementType declType = parseLocalDeclarationRest(detector.isEnumDetected());
1026
1027 if (declType != null) {
1028 // we do not attach preceding comments (non-doc) to local variables because they are likely commenting a few statements below
1029 closeDeclarationWithCommentBinders(decl, declType,
1030 declType != KtNodeTypes.PROPERTY && declType != KtNodeTypes.DESTRUCTURING_DECLARATION);
1031 return true;
1032 }
1033 else {
1034 decl.rollbackTo();
1035 return false;
1036 }
1037 }
1038
1039 /*
1040 * functionLiteral // one can use "it" as a parameter name
1041 * : "{" expressions "}"
1042 * : "{" (modifiers SimpleName){","} "->" statements "}"
1043 * ;
1044 */
1045 private void parseFunctionLiteral() {
1046 parseFunctionLiteral(/* preferBlock = */false);
1047 }
1048
1049 private void parseFunctionLiteral(boolean preferBlock) {
1050 assert _at(LBRACE);
1051
1052 PsiBuilder.Marker literalExpression = mark();
1053
1054 PsiBuilder.Marker literal = mark();
1055
1056 myBuilder.enableNewlines();
1057 advance(); // LBRACE
1058
1059 boolean paramsFound = false;
1060
1061 if (at(ARROW)) {
1062 // { -> ...}
1063 mark().done(VALUE_PARAMETER_LIST);
1064 advance(); // ARROW
1065 paramsFound = true;
1066 }
1067 else {
1068 if (at(IDENTIFIER) || at(COLON)) {
1069 // Try to parse a simple name list followed by an ARROW
1070 // {a -> ...}
1071 // {a, b -> ...}
1072 PsiBuilder.Marker rollbackMarker = mark();
1073 IElementType nextToken = lookahead(1);
1074 boolean preferParamsToExpressions = (nextToken == COMMA || nextToken == COLON);
1075 parseFunctionLiteralShorthandParameterList();
1076
1077 paramsFound = preferParamsToExpressions ?
1078 rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
1079 rollbackOrDropAt(rollbackMarker, ARROW);
1080 }
1081 }
1082
1083 if (!paramsFound) {
1084 if (preferBlock) {
1085 literal.drop();
1086 parseStatements();
1087 expect(RBRACE, "Expecting '}'");
1088 literalExpression.done(BLOCK);
1089 myBuilder.restoreNewlinesState();
1090
1091 return;
1092 }
1093 }
1094
1095 PsiBuilder.Marker body = mark();
1096 parseStatements();
1097 body.done(BLOCK);
1098
1099 expect(RBRACE, "Expecting '}'");
1100 myBuilder.restoreNewlinesState();
1101
1102 literal.done(FUNCTION_LITERAL);
1103 literalExpression.done(LAMBDA_EXPRESSION);
1104 }
1105
1106 private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) {
1107 if (at(dropAt)) {
1108 advance(); // dropAt
1109 rollbackMarker.drop();
1110 return true;
1111 }
1112 rollbackMarker.rollbackTo();
1113 return false;
1114 }
1115
1116 private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker,
1117 KtToken expected, String expectMessage,
1118 IElementType validForDrop) {
1119 if (at(expected)) {
1120 advance(); // dropAt
1121 rollbackMarker.drop();
1122 return true;
1123 }
1124 else if (at(validForDrop)) {
1125 rollbackMarker.drop();
1126 expect(expected, expectMessage);
1127 return true;
1128 }
1129
1130 rollbackMarker.rollbackTo();
1131 return false;
1132 }
1133
1134
1135 /*
1136 * SimpleName{,}
1137 */
1138 private void parseFunctionLiteralShorthandParameterList() {
1139 PsiBuilder.Marker parameterList = mark();
1140
1141 while (!eof()) {
1142 PsiBuilder.Marker parameter = mark();
1143
1144 // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
1145 // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
1146
1147 if (at(COLON)) {
1148 error("Expecting parameter name");
1149 }
1150 else {
1151 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
1152 }
1153
1154 if (at(COLON)) {
1155 advance(); // COLON
1156 myJetParsing.parseTypeRef(TokenSet.create(ARROW, COMMA));
1157 }
1158 parameter.done(VALUE_PARAMETER);
1159
1160 if (at(ARROW)) {
1161 break;
1162 }
1163 else if (at(COMMA)) {
1164 advance(); // COMMA
1165 }
1166 else {
1167 error("Expecting '->' or ','");
1168 break;
1169 }
1170 }
1171
1172 parameterList.done(VALUE_PARAMETER_LIST);
1173 }
1174
1175 /*
1176 * expressions
1177 * : SEMI* statement{SEMI+} SEMI*
1178 */
1179 public void parseStatements() {
1180 parseStatements(false);
1181 }
1182
1183 /*
1184 * expressions
1185 * : SEMI* statement{SEMI+} SEMI*
1186 */
1187 public void parseStatements(boolean isScriptTopLevel) {
1188 while (at(SEMICOLON)) advance(); // SEMICOLON
1189 while (!eof() && !at(RBRACE)) {
1190 if (!atSet(STATEMENT_FIRST)) {
1191 errorAndAdvance("Expecting an element");
1192 }
1193 if (atSet(STATEMENT_FIRST)) {
1194 parseStatement(isScriptTopLevel);
1195 }
1196 if (at(SEMICOLON)) {
1197 while (at(SEMICOLON)) advance(); // SEMICOLON
1198 }
1199 else if (at(RBRACE)) {
1200 break;
1201 }
1202 else if (!myBuilder.newlineBeforeCurrentToken()) {
1203 String severalStatementsError = "Unexpected tokens (use ';' to separate expressions on the same line)";
1204
1205 if (atSet(STATEMENT_NEW_LINE_QUICK_RECOVERY_SET)) {
1206 error(severalStatementsError);
1207 }
1208 else {
1209 errorUntil(severalStatementsError, TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE));
1210 }
1211 }
1212 }
1213 }
1214
1215 /*
1216 * statement
1217 * : expression
1218 * : declaration
1219 * ;
1220 */
1221 private void parseStatement(boolean isScriptTopLevel) {
1222 if (!parseLocalDeclaration()) {
1223 if (!atSet(EXPRESSION_FIRST)) {
1224 errorAndAdvance("Expecting a statement");
1225 }
1226 else if (isScriptTopLevel){
1227 PsiBuilder.Marker scriptInitializer = mark();
1228 parseExpression();
1229 scriptInitializer.done(SCRIPT_INITIALIZER);
1230 }
1231 else {
1232 parseExpression();
1233 }
1234 }
1235 }
1236
1237 /*
1238 * declaration
1239 * : function
1240 * : property
1241 * : extension
1242 * : class
1243 * : typeAlias
1244 * : object
1245 * ;
1246 */
1247 private IElementType parseLocalDeclarationRest(boolean isEnum) {
1248 IElementType keywordToken = tt();
1249 IElementType declType = null;
1250 if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
1251 declType = myJetParsing.parseClass(isEnum);
1252 }
1253 else if (keywordToken == FUN_KEYWORD) {
1254 declType = myJetParsing.parseFunction();
1255 }
1256 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
1257 declType = myJetParsing.parseProperty(true);
1258 }
1259 else if (keywordToken == TYPE_ALIAS_KEYWORD) {
1260 declType = myJetParsing.parseTypeAlias();
1261 }
1262 else if (keywordToken == OBJECT_KEYWORD) {
1263 // Object expression may appear at the statement position: should parse it
1264 // as expression instead of object declaration
1265 // sample:
1266 // {
1267 // object : Thread() {
1268 // }
1269 // }
1270 IElementType lookahead = lookahead(1);
1271 if (lookahead == COLON || lookahead == LBRACE) {
1272 return null;
1273 }
1274
1275 myJetParsing.parseObject(NameParsingMode.REQUIRED, true);
1276 declType = OBJECT_DECLARATION;
1277 }
1278 return declType;
1279 }
1280
1281 /*
1282 * doWhile
1283 * : "do" element "while" "(" element ")"
1284 * ;
1285 */
1286 private void parseDoWhile() {
1287 assert _at(DO_KEYWORD);
1288
1289 PsiBuilder.Marker loop = mark();
1290
1291 advance(); // DO_KEYWORD
1292
1293 if (!at(WHILE_KEYWORD)) {
1294 parseControlStructureBody();
1295 }
1296
1297 if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) {
1298 parseCondition();
1299 }
1300
1301 loop.done(DO_WHILE);
1302 }
1303
1304 /*
1305 * while
1306 * : "while" "(" element ")" element
1307 * ;
1308 */
1309 private void parseWhile() {
1310 assert _at(WHILE_KEYWORD);
1311
1312 PsiBuilder.Marker loop = mark();
1313
1314 advance(); // WHILE_KEYWORD
1315
1316 parseCondition();
1317
1318 parseControlStructureBody();
1319
1320 loop.done(WHILE);
1321 }
1322
1323 /*
1324 * for
1325 * : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
1326 * ;
1327 *
1328 * TODO: empty loop body (at the end of the block)?
1329 */
1330 private void parseFor() {
1331 assert _at(FOR_KEYWORD);
1332
1333 PsiBuilder.Marker loop = mark();
1334
1335 advance(); // FOR_KEYWORD
1336
1337 if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) {
1338 myBuilder.disableNewlines();
1339
1340 if (!at(RPAR)) {
1341 PsiBuilder.Marker parameter = mark();
1342
1343 if (!at(IN_KEYWORD)) {
1344 myJetParsing.parseModifierList(DEFAULT, TokenSet.create(IN_KEYWORD, RPAR, COLON));
1345 }
1346
1347 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
1348
1349 if (at(LPAR)) {
1350 myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
1351 parameter.done(DESTRUCTURING_DECLARATION);
1352 }
1353 else {
1354 expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
1355
1356 if (at(COLON)) {
1357 advance(); // COLON
1358 myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
1359 }
1360 parameter.done(VALUE_PARAMETER);
1361 }
1362
1363 if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
1364 PsiBuilder.Marker range = mark();
1365 parseExpression();
1366 range.done(LOOP_RANGE);
1367 }
1368 }
1369 else {
1370 error("Expecting a variable name");
1371 }
1372
1373 expectNoAdvance(RPAR, "Expecting ')'");
1374 myBuilder.restoreNewlinesState();
1375 }
1376
1377 parseControlStructureBody();
1378
1379 loop.done(FOR);
1380 }
1381
1382 /**
1383 * If it has no ->, it's a block, otherwise a function literal
1384 */
1385 private void parseExpressionPreferringBlocks() {
1386 if (!parseAnnotatedLambda(/* preferBlock = */true)) {
1387 parseExpression();
1388 }
1389 }
1390
1391 /*
1392 * element
1393 */
1394 private void parseControlStructureBody() {
1395 PsiBuilder.Marker body = mark();
1396 if (!at(SEMICOLON)) {
1397 parseExpressionPreferringBlocks();
1398 }
1399 body.done(BODY);
1400 }
1401
1402 /*
1403 * try
1404 * : "try" block catchBlock* finallyBlock?
1405 * ;
1406 * catchBlock
1407 * : "catch" "(" annotations SimpleName ":" userType ")" block
1408 * ;
1409 *
1410 * finallyBlock
1411 * : "finally" block
1412 * ;
1413 */
1414 private void parseTry() {
1415 assert _at(TRY_KEYWORD);
1416
1417 PsiBuilder.Marker tryExpression = mark();
1418
1419 advance(); // TRY_KEYWORD
1420
1421 myJetParsing.parseBlock();
1422
1423 boolean catchOrFinally = false;
1424 while (at(CATCH_KEYWORD)) {
1425 catchOrFinally = true;
1426 PsiBuilder.Marker catchBlock = mark();
1427 advance(); // CATCH_KEYWORD
1428
1429 TokenSet recoverySet = TokenSet.create(LBRACE, RBRACE, FINALLY_KEYWORD, CATCH_KEYWORD);
1430 if (atSet(recoverySet)) {
1431 error("Expecting exception variable declaration");
1432 }
1433 else {
1434 PsiBuilder.Marker parameters = mark();
1435 expect(LPAR, "Expecting '('", recoverySet);
1436 if (!atSet(recoverySet)) {
1437 myJetParsing.parseValueParameter(/*typeRequired = */ true);
1438 expect(RPAR, "Expecting ')'", recoverySet);
1439 }
1440 else {
1441 error("Expecting exception variable declaration");
1442 }
1443 parameters.done(VALUE_PARAMETER_LIST);
1444 }
1445
1446 if (at(LBRACE)) {
1447 myJetParsing.parseBlock();
1448 }
1449 else {
1450 error("Expecting a block: { ... }");
1451 }
1452 catchBlock.done(CATCH);
1453 }
1454
1455 if (at(FINALLY_KEYWORD)) {
1456 catchOrFinally = true;
1457 PsiBuilder.Marker finallyBlock = mark();
1458
1459 advance(); // FINALLY_KEYWORD
1460
1461 myJetParsing.parseBlock();
1462
1463 finallyBlock.done(FINALLY);
1464 }
1465
1466 if (!catchOrFinally) {
1467 error("Expecting 'catch' or 'finally'");
1468 }
1469
1470 tryExpression.done(TRY);
1471 }
1472
1473 /*
1474 * if
1475 * : "if" "(" element ")" element SEMI? ("else" element)?
1476 * ;
1477 */
1478 private void parseIf() {
1479 assert _at(IF_KEYWORD);
1480
1481 PsiBuilder.Marker marker = mark();
1482
1483 advance(); //IF_KEYWORD
1484
1485 parseCondition();
1486
1487 PsiBuilder.Marker thenBranch = mark();
1488 if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) {
1489 parseExpressionPreferringBlocks();
1490 }
1491 if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) {
1492 advance(); // SEMICOLON
1493 }
1494 thenBranch.done(THEN);
1495
1496 // lookahead for arrow is needed to prevent capturing of whenEntry like "else -> "
1497 if (at(ELSE_KEYWORD) && lookahead(1) != ARROW) {
1498 advance(); // ELSE_KEYWORD
1499
1500 PsiBuilder.Marker elseBranch = mark();
1501 if (!at(SEMICOLON)) {
1502 parseExpressionPreferringBlocks();
1503 }
1504 elseBranch.done(ELSE);
1505 }
1506
1507 marker.done(IF);
1508 }
1509
1510 /*
1511 * "(" element ")"
1512 */
1513 private void parseCondition() {
1514 myBuilder.disableNewlines();
1515
1516 if (expect(LPAR, "Expecting a condition in parentheses '(...)'", EXPRESSION_FIRST)) {
1517 PsiBuilder.Marker condition = mark();
1518 parseExpression();
1519 condition.done(CONDITION);
1520 expect(RPAR, "Expecting ')");
1521 }
1522
1523 myBuilder.restoreNewlinesState();
1524 }
1525
1526 /*
1527 * : "continue" getEntryPoint?
1528 * : "break" getEntryPoint?
1529 */
1530 private void parseJump(KtNodeType type) {
1531 assert _at(BREAK_KEYWORD) || _at(CONTINUE_KEYWORD);
1532
1533 PsiBuilder.Marker marker = mark();
1534
1535 advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
1536
1537 parseLabelReferenceWithNoWhitespace();
1538
1539 marker.done(type);
1540 }
1541
1542 /*
1543 * "return" getEntryPoint? element?
1544 */
1545 private void parseReturn() {
1546 assert _at(RETURN_KEYWORD);
1547
1548 PsiBuilder.Marker returnExpression = mark();
1549
1550 advance(); // RETURN_KEYWORD
1551
1552 parseLabelReferenceWithNoWhitespace();
1553
1554 if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
1555
1556 returnExpression.done(RETURN);
1557 }
1558
1559 /*
1560 * labelReference?
1561 */
1562 private void parseLabelReferenceWithNoWhitespace() {
1563 if (at(AT) && !myBuilder.newlineBeforeCurrentToken()) {
1564 if (WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) {
1565 error("There should be no space or comments before '@' in label reference");
1566 }
1567 parseLabelReference();
1568 }
1569 }
1570
1571 /*
1572 * IDENTIFIER "@"
1573 */
1574 private void parseLabelDefinition() {
1575 if (at(AT)) {
1576 // recovery for empty label identifier
1577 errorAndAdvance("Label must be named"); // AT
1578 return;
1579 }
1580
1581 PsiBuilder.Marker labelWrap = mark();
1582 PsiBuilder.Marker mark = mark();
1583
1584 assert _at(IDENTIFIER) && myBuilder.rawLookup(1) == AT : "Callers must check that current token is IDENTIFIER followed with '@'";
1585
1586 advance(); // IDENTIFIER
1587 advance(); // AT
1588
1589 mark.done(LABEL);
1590
1591 labelWrap.done(LABEL_QUALIFIER);
1592 }
1593
1594 /*
1595 * "@" IDENTIFIER
1596 */
1597 private void parseLabelReference() {
1598 assert _at(AT);
1599
1600 PsiBuilder.Marker labelWrap = mark();
1601
1602 PsiBuilder.Marker mark = mark();
1603
1604 if (myBuilder.rawLookup(1) != IDENTIFIER) {
1605 errorAndAdvance("Label must be named"); // AT
1606 labelWrap.drop();
1607 mark.drop();
1608 return;
1609 }
1610
1611 advance(); // AT
1612 advance(); // IDENTIFIER
1613
1614 mark.done(LABEL);
1615
1616 labelWrap.done(LABEL_QUALIFIER);
1617 }
1618
1619 /*
1620 * : "throw" element
1621 */
1622 private void parseThrow() {
1623 assert _at(THROW_KEYWORD);
1624
1625 PsiBuilder.Marker marker = mark();
1626
1627 advance(); // THROW_KEYWORD
1628
1629 parseExpression();
1630
1631 marker.done(THROW);
1632 }
1633
1634 /*
1635 * "(" expression ")"
1636 */
1637 private void parseParenthesizedExpression() {
1638 assert _at(LPAR);
1639
1640 PsiBuilder.Marker mark = mark();
1641
1642 myBuilder.disableNewlines();
1643 advance(); // LPAR
1644 if (at(RPAR)) {
1645 error("Expecting an expression");
1646 }
1647 else {
1648 parseExpression();
1649 }
1650
1651 expect(RPAR, "Expecting ')'");
1652 myBuilder.restoreNewlinesState();
1653
1654 mark.done(PARENTHESIZED);
1655 }
1656
1657 /*
1658 * "this" label?
1659 */
1660 private void parseThisExpression() {
1661 assert _at(THIS_KEYWORD);
1662 PsiBuilder.Marker mark = mark();
1663
1664 PsiBuilder.Marker thisReference = mark();
1665 advance(); // THIS_KEYWORD
1666 thisReference.done(REFERENCE_EXPRESSION);
1667
1668 parseLabelReferenceWithNoWhitespace();
1669
1670 mark.done(THIS_EXPRESSION);
1671 }
1672
1673 /*
1674 * "this" ("<" type ">")? label?
1675 */
1676 private void parseSuperExpression() {
1677 assert _at(SUPER_KEYWORD);
1678 PsiBuilder.Marker mark = mark();
1679
1680 PsiBuilder.Marker superReference = mark();
1681 advance(); // SUPER_KEYWORD
1682 superReference.done(REFERENCE_EXPRESSION);
1683
1684 if (at(LT)) {
1685 // This may be "super < foo" or "super<foo>", thus the backtracking
1686 PsiBuilder.Marker supertype = mark();
1687
1688 myBuilder.disableNewlines();
1689 advance(); // LT
1690
1691 myJetParsing.parseTypeRef();
1692
1693 if (at(GT)) {
1694 advance(); // GT
1695 supertype.drop();
1696 }
1697 else {
1698 supertype.rollbackTo();
1699 }
1700 myBuilder.restoreNewlinesState();
1701 }
1702 parseLabelReferenceWithNoWhitespace();
1703
1704 mark.done(SUPER_EXPRESSION);
1705 }
1706
1707 /*
1708 * valueArguments
1709 * : "(" (SimpleName "=")? "*"? element{","} ")"
1710 * ;
1711 */
1712 public void parseValueArgumentList() {
1713 PsiBuilder.Marker list = mark();
1714
1715 myBuilder.disableNewlines();
1716
1717 if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) {
1718 if (!at(RPAR)) {
1719 while (true) {
1720 while (at(COMMA)) errorAndAdvance("Expecting an argument");
1721 parseValueArgument();
1722 if (at(COLON) && lookahead(1) == IDENTIFIER) {
1723 errorAndAdvance("Unexpected type specification", 2);
1724 }
1725 if (!at(COMMA)) break;
1726 advance(); // COMMA
1727 if (at(RPAR)) {
1728 error("Expecting an argument");
1729 break;
1730 }
1731 }
1732 }
1733
1734 expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW);
1735 }
1736
1737 myBuilder.restoreNewlinesState();
1738
1739 list.done(VALUE_ARGUMENT_LIST);
1740 }
1741
1742 /*
1743 * (SimpleName "=")? "*"? element
1744 */
1745 private void parseValueArgument() {
1746 PsiBuilder.Marker argument = mark();
1747 if (at(IDENTIFIER) && lookahead(1) == EQ) {
1748 PsiBuilder.Marker argName = mark();
1749 PsiBuilder.Marker reference = mark();
1750 advance(); // IDENTIFIER
1751 reference.done(REFERENCE_EXPRESSION);
1752 argName.done(VALUE_ARGUMENT_NAME);
1753 advance(); // EQ
1754 }
1755 if (at(MUL)) {
1756 advance(); // MUL
1757 }
1758 parseExpression();
1759 argument.done(VALUE_ARGUMENT);
1760 }
1761
1762 /*
1763 * "object" (":" delegationSpecifier{","})? classBody // Cannot make class body optional: foo(object : F, A)
1764 */
1765 public void parseObjectLiteral() {
1766 PsiBuilder.Marker literal = mark();
1767 PsiBuilder.Marker declaration = mark();
1768 myJetParsing.parseObject(NameParsingMode.PROHIBITED, false); // Body is not optional because of foo(object : A, B)
1769 declaration.done(OBJECT_DECLARATION);
1770 literal.done(OBJECT_LITERAL);
1771 }
1772
1773 private void parseOneTokenExpression(KtNodeType type) {
1774 PsiBuilder.Marker mark = mark();
1775 advance();
1776 mark.done(type);
1777 }
1778
1779 @Override
1780 protected KotlinParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1781 return myJetParsing.create(builder);
1782 }
1783
1784 private boolean interruptedWithNewLine() {
1785 return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
1786 }
1787 }