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 while (at(SEMICOLON)) advance(); // SEMICOLON
1185 while (!eof() && !at(RBRACE)) {
1186 if (!atSet(STATEMENT_FIRST)) {
1187 errorAndAdvance("Expecting an element");
1188 }
1189 if (atSet(STATEMENT_FIRST)) {
1190 parseStatement();
1191 }
1192 if (at(SEMICOLON)) {
1193 while (at(SEMICOLON)) advance(); // SEMICOLON
1194 }
1195 else if (at(RBRACE)) {
1196 break;
1197 }
1198 else if (!myBuilder.newlineBeforeCurrentToken()) {
1199 String severalStatementsError = "Unexpected tokens (use ';' to separate expressions on the same line)";
1200
1201 if (atSet(STATEMENT_NEW_LINE_QUICK_RECOVERY_SET)) {
1202 error(severalStatementsError);
1203 }
1204 else {
1205 errorUntil(severalStatementsError, TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE));
1206 }
1207 }
1208 }
1209 }
1210
1211 /*
1212 * statement
1213 * : expression
1214 * : declaration
1215 * ;
1216 */
1217 private void parseStatement() {
1218 if (!parseLocalDeclaration()) {
1219 if (!atSet(EXPRESSION_FIRST)) {
1220 errorAndAdvance("Expecting a statement");
1221 }
1222 else {
1223 parseExpression();
1224 }
1225 }
1226 }
1227
1228 /*
1229 * declaration
1230 * : function
1231 * : property
1232 * : extension
1233 * : class
1234 * : typeAlias
1235 * : object
1236 * ;
1237 */
1238 private IElementType parseLocalDeclarationRest(boolean isEnum) {
1239 IElementType keywordToken = tt();
1240 IElementType declType = null;
1241 if (keywordToken == CLASS_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
1242 declType = myJetParsing.parseClass(isEnum);
1243 }
1244 else if (keywordToken == FUN_KEYWORD) {
1245 declType = myJetParsing.parseFunction();
1246 }
1247 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
1248 declType = myJetParsing.parseProperty(true);
1249 }
1250 else if (keywordToken == TYPE_ALIAS_KEYWORD) {
1251 declType = myJetParsing.parseTypeAlias();
1252 }
1253 else if (keywordToken == OBJECT_KEYWORD) {
1254 // Object expression may appear at the statement position: should parse it
1255 // as expression instead of object declaration
1256 // sample:
1257 // {
1258 // object : Thread() {
1259 // }
1260 // }
1261 IElementType lookahead = lookahead(1);
1262 if (lookahead == COLON || lookahead == LBRACE) {
1263 return null;
1264 }
1265
1266 myJetParsing.parseObject(NameParsingMode.REQUIRED, true);
1267 declType = OBJECT_DECLARATION;
1268 }
1269 return declType;
1270 }
1271
1272 /*
1273 * doWhile
1274 * : "do" element "while" "(" element ")"
1275 * ;
1276 */
1277 private void parseDoWhile() {
1278 assert _at(DO_KEYWORD);
1279
1280 PsiBuilder.Marker loop = mark();
1281
1282 advance(); // DO_KEYWORD
1283
1284 if (!at(WHILE_KEYWORD)) {
1285 parseControlStructureBody();
1286 }
1287
1288 if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) {
1289 parseCondition();
1290 }
1291
1292 loop.done(DO_WHILE);
1293 }
1294
1295 /*
1296 * while
1297 * : "while" "(" element ")" element
1298 * ;
1299 */
1300 private void parseWhile() {
1301 assert _at(WHILE_KEYWORD);
1302
1303 PsiBuilder.Marker loop = mark();
1304
1305 advance(); // WHILE_KEYWORD
1306
1307 parseCondition();
1308
1309 parseControlStructureBody();
1310
1311 loop.done(WHILE);
1312 }
1313
1314 /*
1315 * for
1316 * : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
1317 * ;
1318 *
1319 * TODO: empty loop body (at the end of the block)?
1320 */
1321 private void parseFor() {
1322 assert _at(FOR_KEYWORD);
1323
1324 PsiBuilder.Marker loop = mark();
1325
1326 advance(); // FOR_KEYWORD
1327
1328 if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) {
1329 myBuilder.disableNewlines();
1330
1331 if (!at(RPAR)) {
1332 PsiBuilder.Marker parameter = mark();
1333
1334 if (!at(IN_KEYWORD)) {
1335 myJetParsing.parseModifierList(DEFAULT, TokenSet.create(IN_KEYWORD, RPAR, COLON));
1336 }
1337
1338 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
1339
1340 if (at(LPAR)) {
1341 myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
1342 parameter.done(MULTI_VARIABLE_DECLARATION);
1343 }
1344 else {
1345 expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));
1346
1347 if (at(COLON)) {
1348 advance(); // COLON
1349 myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
1350 }
1351 parameter.done(VALUE_PARAMETER);
1352 }
1353
1354 if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
1355 PsiBuilder.Marker range = mark();
1356 parseExpression();
1357 range.done(LOOP_RANGE);
1358 }
1359 }
1360 else {
1361 error("Expecting a variable name");
1362 }
1363
1364 expectNoAdvance(RPAR, "Expecting ')'");
1365 myBuilder.restoreNewlinesState();
1366 }
1367
1368 parseControlStructureBody();
1369
1370 loop.done(FOR);
1371 }
1372
1373 /**
1374 * If it has no ->, it's a block, otherwise a function literal
1375 */
1376 private void parseExpressionPreferringBlocks() {
1377 if (!parseAnnotatedLambda(/* preferBlock = */true)) {
1378 parseExpression();
1379 }
1380 }
1381
1382 /*
1383 * element
1384 */
1385 private void parseControlStructureBody() {
1386 PsiBuilder.Marker body = mark();
1387 if (!at(SEMICOLON)) {
1388 parseExpressionPreferringBlocks();
1389 }
1390 body.done(BODY);
1391 }
1392
1393 /*
1394 * try
1395 * : "try" block catchBlock* finallyBlock?
1396 * ;
1397 * catchBlock
1398 * : "catch" "(" annotations SimpleName ":" userType ")" block
1399 * ;
1400 *
1401 * finallyBlock
1402 * : "finally" block
1403 * ;
1404 */
1405 private void parseTry() {
1406 assert _at(TRY_KEYWORD);
1407
1408 PsiBuilder.Marker tryExpression = mark();
1409
1410 advance(); // TRY_KEYWORD
1411
1412 myJetParsing.parseBlock();
1413
1414 boolean catchOrFinally = false;
1415 while (at(CATCH_KEYWORD)) {
1416 catchOrFinally = true;
1417 PsiBuilder.Marker catchBlock = mark();
1418 advance(); // CATCH_KEYWORD
1419
1420 TokenSet recoverySet = TokenSet.create(LBRACE, RBRACE, FINALLY_KEYWORD, CATCH_KEYWORD);
1421 if (atSet(recoverySet)) {
1422 error("Expecting exception variable declaration");
1423 }
1424 else {
1425 PsiBuilder.Marker parameters = mark();
1426 expect(LPAR, "Expecting '('", recoverySet);
1427 if (!atSet(recoverySet)) {
1428 myJetParsing.parseValueParameter(/*typeRequired = */ true);
1429 expect(RPAR, "Expecting ')'", recoverySet);
1430 }
1431 else {
1432 error("Expecting exception variable declaration");
1433 }
1434 parameters.done(VALUE_PARAMETER_LIST);
1435 }
1436
1437 if (at(LBRACE)) {
1438 myJetParsing.parseBlock();
1439 }
1440 else {
1441 error("Expecting a block: { ... }");
1442 }
1443 catchBlock.done(CATCH);
1444 }
1445
1446 if (at(FINALLY_KEYWORD)) {
1447 catchOrFinally = true;
1448 PsiBuilder.Marker finallyBlock = mark();
1449
1450 advance(); // FINALLY_KEYWORD
1451
1452 myJetParsing.parseBlock();
1453
1454 finallyBlock.done(FINALLY);
1455 }
1456
1457 if (!catchOrFinally) {
1458 error("Expecting 'catch' or 'finally'");
1459 }
1460
1461 tryExpression.done(TRY);
1462 }
1463
1464 /*
1465 * if
1466 * : "if" "(" element ")" element SEMI? ("else" element)?
1467 * ;
1468 */
1469 private void parseIf() {
1470 assert _at(IF_KEYWORD);
1471
1472 PsiBuilder.Marker marker = mark();
1473
1474 advance(); //IF_KEYWORD
1475
1476 parseCondition();
1477
1478 PsiBuilder.Marker thenBranch = mark();
1479 if (!at(ELSE_KEYWORD) && !at(SEMICOLON)) {
1480 parseExpressionPreferringBlocks();
1481 }
1482 if (at(SEMICOLON) && lookahead(1) == ELSE_KEYWORD) {
1483 advance(); // SEMICOLON
1484 }
1485 thenBranch.done(THEN);
1486
1487 if (at(ELSE_KEYWORD)) {
1488 advance(); // ELSE_KEYWORD
1489
1490 PsiBuilder.Marker elseBranch = mark();
1491 if (!at(SEMICOLON)) {
1492 parseExpressionPreferringBlocks();
1493 }
1494 elseBranch.done(ELSE);
1495 }
1496
1497 marker.done(IF);
1498 }
1499
1500 /*
1501 * "(" element ")"
1502 */
1503 private void parseCondition() {
1504 myBuilder.disableNewlines();
1505
1506 if (expect(LPAR, "Expecting a condition in parentheses '(...)'", EXPRESSION_FIRST)) {
1507 PsiBuilder.Marker condition = mark();
1508 parseExpression();
1509 condition.done(CONDITION);
1510 expect(RPAR, "Expecting ')");
1511 }
1512
1513 myBuilder.restoreNewlinesState();
1514 }
1515
1516 /*
1517 * : "continue" getEntryPoint?
1518 * : "break" getEntryPoint?
1519 */
1520 private void parseJump(KtNodeType type) {
1521 assert _at(BREAK_KEYWORD) || _at(CONTINUE_KEYWORD);
1522
1523 PsiBuilder.Marker marker = mark();
1524
1525 advance(); // BREAK_KEYWORD or CONTINUE_KEYWORD
1526
1527 parseLabelReferenceWithNoWhitespace();
1528
1529 marker.done(type);
1530 }
1531
1532 /*
1533 * "return" getEntryPoint? element?
1534 */
1535 private void parseReturn() {
1536 assert _at(RETURN_KEYWORD);
1537
1538 PsiBuilder.Marker returnExpression = mark();
1539
1540 advance(); // RETURN_KEYWORD
1541
1542 parseLabelReferenceWithNoWhitespace();
1543
1544 if (atSet(EXPRESSION_FIRST) && !at(EOL_OR_SEMICOLON)) parseExpression();
1545
1546 returnExpression.done(RETURN);
1547 }
1548
1549 /*
1550 * labelReference?
1551 */
1552 private void parseLabelReferenceWithNoWhitespace() {
1553 if (at(AT) && !myBuilder.newlineBeforeCurrentToken()) {
1554 if (WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1))) {
1555 error("There should be no space or comments before '@' in label reference");
1556 }
1557 parseLabelReference();
1558 }
1559 }
1560
1561 /*
1562 * IDENTIFIER "@"
1563 */
1564 private void parseLabelDefinition() {
1565 if (at(AT)) {
1566 // recovery for empty label identifier
1567 errorAndAdvance("Label must be named"); // AT
1568 return;
1569 }
1570
1571 PsiBuilder.Marker labelWrap = mark();
1572 PsiBuilder.Marker mark = mark();
1573
1574 assert _at(IDENTIFIER) && myBuilder.rawLookup(1) == AT : "Callers must check that current token is IDENTIFIER followed with '@'";
1575
1576 advance(); // IDENTIFIER
1577 advance(); // AT
1578
1579 mark.done(LABEL);
1580
1581 labelWrap.done(LABEL_QUALIFIER);
1582 }
1583
1584 /*
1585 * "@" IDENTIFIER
1586 */
1587 private void parseLabelReference() {
1588 assert _at(AT);
1589
1590 PsiBuilder.Marker labelWrap = mark();
1591
1592 PsiBuilder.Marker mark = mark();
1593
1594 if (myBuilder.rawLookup(1) != IDENTIFIER) {
1595 errorAndAdvance("Label must be named"); // AT
1596 labelWrap.drop();
1597 mark.drop();
1598 return;
1599 }
1600
1601 advance(); // AT
1602 advance(); // IDENTIFIER
1603
1604 mark.done(LABEL);
1605
1606 labelWrap.done(LABEL_QUALIFIER);
1607 }
1608
1609 /*
1610 * : "throw" element
1611 */
1612 private void parseThrow() {
1613 assert _at(THROW_KEYWORD);
1614
1615 PsiBuilder.Marker marker = mark();
1616
1617 advance(); // THROW_KEYWORD
1618
1619 parseExpression();
1620
1621 marker.done(THROW);
1622 }
1623
1624 /*
1625 * "(" expression ")"
1626 */
1627 private void parseParenthesizedExpression() {
1628 assert _at(LPAR);
1629
1630 PsiBuilder.Marker mark = mark();
1631
1632 myBuilder.disableNewlines();
1633 advance(); // LPAR
1634 if (at(RPAR)) {
1635 error("Expecting an expression");
1636 }
1637 else {
1638 parseExpression();
1639 }
1640
1641 expect(RPAR, "Expecting ')'");
1642 myBuilder.restoreNewlinesState();
1643
1644 mark.done(PARENTHESIZED);
1645 }
1646
1647 /*
1648 * "this" label?
1649 */
1650 private void parseThisExpression() {
1651 assert _at(THIS_KEYWORD);
1652 PsiBuilder.Marker mark = mark();
1653
1654 PsiBuilder.Marker thisReference = mark();
1655 advance(); // THIS_KEYWORD
1656 thisReference.done(REFERENCE_EXPRESSION);
1657
1658 parseLabelReferenceWithNoWhitespace();
1659
1660 mark.done(THIS_EXPRESSION);
1661 }
1662
1663 /*
1664 * "this" ("<" type ">")? label?
1665 */
1666 private void parseSuperExpression() {
1667 assert _at(SUPER_KEYWORD);
1668 PsiBuilder.Marker mark = mark();
1669
1670 PsiBuilder.Marker superReference = mark();
1671 advance(); // SUPER_KEYWORD
1672 superReference.done(REFERENCE_EXPRESSION);
1673
1674 if (at(LT)) {
1675 // This may be "super < foo" or "super<foo>", thus the backtracking
1676 PsiBuilder.Marker supertype = mark();
1677
1678 myBuilder.disableNewlines();
1679 advance(); // LT
1680
1681 myJetParsing.parseTypeRef();
1682
1683 if (at(GT)) {
1684 advance(); // GT
1685 supertype.drop();
1686 }
1687 else {
1688 supertype.rollbackTo();
1689 }
1690 myBuilder.restoreNewlinesState();
1691 }
1692 parseLabelReferenceWithNoWhitespace();
1693
1694 mark.done(SUPER_EXPRESSION);
1695 }
1696
1697 /*
1698 * valueArguments
1699 * : "(" (SimpleName "=")? "*"? element{","} ")"
1700 * ;
1701 */
1702 public void parseValueArgumentList() {
1703 PsiBuilder.Marker list = mark();
1704
1705 myBuilder.disableNewlines();
1706
1707 if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) {
1708 if (!at(RPAR)) {
1709 while (true) {
1710 while (at(COMMA)) errorAndAdvance("Expecting an argument");
1711 parseValueArgument();
1712 if (at(COLON) && lookahead(1) == IDENTIFIER) {
1713 errorAndAdvance("Unexpected type specification", 2);
1714 }
1715 if (!at(COMMA)) break;
1716 advance(); // COMMA
1717 if (at(RPAR)) {
1718 error("Expecting an argument");
1719 break;
1720 }
1721 }
1722 }
1723
1724 expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW);
1725 }
1726
1727 myBuilder.restoreNewlinesState();
1728
1729 list.done(VALUE_ARGUMENT_LIST);
1730 }
1731
1732 /*
1733 * (SimpleName "=")? "*"? element
1734 */
1735 private void parseValueArgument() {
1736 PsiBuilder.Marker argument = mark();
1737 if (at(IDENTIFIER) && lookahead(1) == EQ) {
1738 PsiBuilder.Marker argName = mark();
1739 PsiBuilder.Marker reference = mark();
1740 advance(); // IDENTIFIER
1741 reference.done(REFERENCE_EXPRESSION);
1742 argName.done(VALUE_ARGUMENT_NAME);
1743 advance(); // EQ
1744 }
1745 if (at(MUL)) {
1746 advance(); // MUL
1747 }
1748 parseExpression();
1749 argument.done(VALUE_ARGUMENT);
1750 }
1751
1752 /*
1753 * "object" (":" delegationSpecifier{","})? classBody // Cannot make class body optional: foo(object : F, A)
1754 */
1755 public void parseObjectLiteral() {
1756 PsiBuilder.Marker literal = mark();
1757 PsiBuilder.Marker declaration = mark();
1758 myJetParsing.parseObject(NameParsingMode.PROHIBITED, false); // Body is not optional because of foo(object : A, B)
1759 declaration.done(OBJECT_DECLARATION);
1760 literal.done(OBJECT_LITERAL);
1761 }
1762
1763 private void parseOneTokenExpression(KtNodeType type) {
1764 PsiBuilder.Marker mark = mark();
1765 advance();
1766 mark.done(type);
1767 }
1768
1769 @Override
1770 protected KotlinParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
1771 return myJetParsing.create(builder);
1772 }
1773
1774 private boolean interruptedWithNewLine() {
1775 return !ALLOW_NEWLINE_OPERATIONS.contains(tt()) && myBuilder.newlineBeforeCurrentToken();
1776 }
1777 }