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