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