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.intellij.lang.PsiBuilder;
020 import com.intellij.openapi.diagnostic.Logger;
021 import com.intellij.psi.tree.IElementType;
022 import com.intellij.psi.tree.TokenSet;
023 import org.jetbrains.annotations.NotNull;
024 import org.jetbrains.annotations.Nullable;
025 import org.jetbrains.kotlin.JetNodeType;
026 import org.jetbrains.kotlin.lexer.JetKeywordToken;
027 import org.jetbrains.kotlin.lexer.JetTokens;
028
029 import java.util.HashMap;
030 import java.util.Map;
031
032 import static org.jetbrains.kotlin.JetNodeTypes.*;
033 import static org.jetbrains.kotlin.lexer.JetTokens.*;
034 import static org.jetbrains.kotlin.parsing.JetParsing.AnnotationParsingMode.*;
035 import static org.jetbrains.kotlin.parsing.JetParsing.DeclarationParsingMode.*;
036
037 public class JetParsing extends AbstractJetParsing {
038 private static final Logger LOG = Logger.getInstance(JetParsing.class);
039
040 // TODO: token sets to constants, including derived methods
041 public static final Map<String, IElementType> MODIFIER_KEYWORD_MAP = new HashMap<String, IElementType>();
042 static {
043 for (IElementType softKeyword : MODIFIER_KEYWORDS.getTypes()) {
044 MODIFIER_KEYWORD_MAP.put(((JetKeywordToken) softKeyword).getValue(), softKeyword);
045 }
046 }
047
048 private static final TokenSet TOP_LEVEL_DECLARATION_FIRST = TokenSet.create(
049 TYPE_ALIAS_KEYWORD, TRAIT_KEYWORD, INTERFACE_KEYWORD, CLASS_KEYWORD, OBJECT_KEYWORD,
050 FUN_KEYWORD, VAL_KEYWORD, PACKAGE_KEYWORD);
051 private static final TokenSet DECLARATION_FIRST = TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST,
052 TokenSet.create(INIT_KEYWORD, GET_KEYWORD, SET_KEYWORD, CONSTRUCTOR_KEYWORD));
053
054 private static final TokenSet CLASS_NAME_RECOVERY_SET = TokenSet.orSet(TokenSet.create(LT, LPAR, COLON, LBRACE),
055 TOP_LEVEL_DECLARATION_FIRST);
056 private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, LPAR, COLON, LBRACE, GT);
057 private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR);
058 private static final TokenSet PACKAGE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON);
059 private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON);
060 /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, CAPITALIZED_THIS_KEYWORD, HASH, DYNAMIC_KEYWORD);
061 private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS);
062 private static final TokenSet VALUE_PARAMETER_FIRST =
063 TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD), MODIFIER_KEYWORDS);
064 private static final TokenSet LAMBDA_VALUE_PARAMETER_FIRST =
065 TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS);
066 private static final TokenSet SOFT_KEYWORDS_AT_MEMBER_START = TokenSet.create(CONSTRUCTOR_KEYWORD, INIT_KEYWORD);
067 private static final TokenSet ANNOTATION_TARGETS = TokenSet.create(
068 FILE_KEYWORD, FIELD_KEYWORD, GET_KEYWORD, SET_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SPARAM_KEYWORD);
069
070 static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) {
071 JetParsing jetParsing = new JetParsing(builder);
072 jetParsing.myExpressionParsing = new JetExpressionParsing(builder, jetParsing);
073 return jetParsing;
074 }
075
076 private static JetParsing createForByClause(SemanticWhitespaceAwarePsiBuilder builder) {
077 final SemanticWhitespaceAwarePsiBuilderForByClause builderForByClause = new SemanticWhitespaceAwarePsiBuilderForByClause(builder);
078 JetParsing jetParsing = new JetParsing(builderForByClause);
079 jetParsing.myExpressionParsing = new JetExpressionParsing(builderForByClause, jetParsing) {
080 @Override
081 protected boolean parseCallWithClosure() {
082 if (builderForByClause.getStackSize() > 0) {
083 return super.parseCallWithClosure();
084 }
085 return false;
086 }
087
088 @Override
089 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
090 return createForByClause(builder);
091 }
092 };
093 return jetParsing;
094 }
095
096 private JetExpressionParsing myExpressionParsing;
097
098 private JetParsing(SemanticWhitespaceAwarePsiBuilder builder) {
099 super(builder);
100 }
101
102 /*
103 * [start] jetlFile
104 * : preamble toplevelObject* [eof]
105 * ;
106 */
107 void parseFile() {
108 PsiBuilder.Marker fileMarker = mark();
109
110 parsePreamble();
111
112 while (!eof()) {
113 parseTopLevelDeclaration();
114 }
115
116 fileMarker.done(JET_FILE);
117 }
118
119 void parseTypeCodeFragment() {
120 PsiBuilder.Marker marker = mark();
121 parseTypeRef();
122
123 checkForUnexpectedSymbols();
124
125 marker.done(TYPE_CODE_FRAGMENT);
126 }
127
128 void parseExpressionCodeFragment() {
129 PsiBuilder.Marker marker = mark();
130 myExpressionParsing.parseExpression();
131
132 checkForUnexpectedSymbols();
133
134 marker.done(EXPRESSION_CODE_FRAGMENT);
135 }
136
137 void parseBlockCodeFragment() {
138 PsiBuilder.Marker marker = mark();
139 PsiBuilder.Marker blockMarker = mark();
140
141 if (at(PACKAGE_KEYWORD) || at(IMPORT_KEYWORD)) {
142 PsiBuilder.Marker err = mark();
143 parsePreamble();
144 err.error("Package directive and imports are forbidden in code fragments");
145 }
146
147 myExpressionParsing.parseStatements();
148
149 checkForUnexpectedSymbols();
150
151 blockMarker.done(BLOCK);
152 marker.done(BLOCK_CODE_FRAGMENT);
153 }
154
155 void parseScript() {
156 PsiBuilder.Marker fileMarker = mark();
157
158 parsePreamble();
159
160 PsiBuilder.Marker scriptMarker = mark();
161
162 PsiBuilder.Marker blockMarker = mark();
163
164 myExpressionParsing.parseStatements();
165
166 checkForUnexpectedSymbols();
167
168 blockMarker.done(BLOCK);
169 scriptMarker.done(SCRIPT);
170 fileMarker.done(JET_FILE);
171 }
172
173 private void checkForUnexpectedSymbols() {
174 while (!eof()) {
175 errorAndAdvance("unexpected symbol");
176 }
177 }
178
179 /*
180 *preamble
181 * : fileAnnotationList? packageDirective? import*
182 * ;
183 */
184 private void parsePreamble() {
185 PsiBuilder.Marker firstEntry = mark();
186
187 /*
188 * fileAnnotationList
189 * : fileAnnotations*
190 */
191 parseFileAnnotationList(FILE_ANNOTATIONS_BEFORE_PACKAGE);
192
193 /*
194 * packageDirective
195 * : modifiers "package" SimpleName{"."} SEMI?
196 * ;
197 */
198 PsiBuilder.Marker packageDirective = mark();
199 parseModifierList(ALLOW_UNESCAPED_REGULAR_ANNOTATIONS);
200
201 if (at(PACKAGE_KEYWORD)) {
202 advance(); // PACKAGE_KEYWORD
203
204 parsePackageName();
205
206 firstEntry.drop();
207
208 consumeIf(SEMICOLON);
209
210 packageDirective.done(PACKAGE_DIRECTIVE);
211 }
212 else {
213 // When package directive is omitted we should not report error on non-file annotations at the beginning of the file.
214 // So, we rollback the parsing position and reparse file annotation list without report error on non-file annotations.
215 firstEntry.rollbackTo();
216
217 parseFileAnnotationList(FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED);
218 packageDirective = mark();
219 packageDirective.done(PACKAGE_DIRECTIVE);
220 // this is necessary to allow comments at the start of the file to be bound to the first declaration
221 packageDirective.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null);
222 }
223
224 parseImportDirectives();
225 }
226
227 /* SimpleName{"."} */
228 private void parsePackageName() {
229 PsiBuilder.Marker qualifiedExpression = mark();
230 boolean simpleName = true;
231 while (true) {
232 if (myBuilder.newlineBeforeCurrentToken()) {
233 errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", PACKAGE_NAME_RECOVERY_SET);
234 break;
235 }
236
237 if (at(DOT)) {
238 advance(); // DOT
239 qualifiedExpression.error("Package name must be a '.'-separated identifier list");
240 qualifiedExpression = mark();
241 continue;
242 }
243
244 PsiBuilder.Marker nsName = mark();
245 boolean simpleNameFound = expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", PACKAGE_NAME_RECOVERY_SET);
246 if (simpleNameFound) {
247 nsName.done(REFERENCE_EXPRESSION);
248 }
249 else {
250 nsName.drop();
251 }
252
253 if (!simpleName) {
254 PsiBuilder.Marker precedingMarker = qualifiedExpression.precede();
255 qualifiedExpression.done(DOT_QUALIFIED_EXPRESSION);
256 qualifiedExpression = precedingMarker;
257 }
258
259 if (at(DOT)) {
260 advance(); // DOT
261
262 if (simpleName && !simpleNameFound) {
263 qualifiedExpression.drop();
264 qualifiedExpression = mark();
265 }
266 else {
267 simpleName = false;
268 }
269 }
270 else {
271 break;
272 }
273 }
274 qualifiedExpression.drop();
275 }
276
277 /*
278 * import
279 * : "import" SimpleName{"."} ("." "*" | "as" SimpleName)? SEMI?
280 * ;
281 */
282 private void parseImportDirective() {
283 assert _at(IMPORT_KEYWORD);
284 PsiBuilder.Marker importDirective = mark();
285 advance(); // IMPORT_KEYWORD
286
287 if (closeImportWithErrorIfNewline(importDirective, "Expecting qualified name")) {
288 return;
289 }
290
291 if (!at(IDENTIFIER)) {
292 PsiBuilder.Marker error = mark();
293 skipUntil(TokenSet.create(EOL_OR_SEMICOLON));
294 error.error("Expecting qualified name");
295 importDirective.done(IMPORT_DIRECTIVE);
296 consumeIf(SEMICOLON);
297 return;
298 }
299
300 PsiBuilder.Marker qualifiedName = mark();
301 PsiBuilder.Marker reference = mark();
302 advance(); // IDENTIFIER
303 reference.done(REFERENCE_EXPRESSION);
304
305 while (at(DOT) && lookahead(1) != MUL) {
306 advance(); // DOT
307
308 if (closeImportWithErrorIfNewline(importDirective, "Import must be placed on a single line")) {
309 qualifiedName.drop();
310 return;
311 }
312
313 reference = mark();
314 if (expect(IDENTIFIER, "Qualified name must be a '.'-separated identifier list", IMPORT_RECOVERY_SET)) {
315 reference.done(REFERENCE_EXPRESSION);
316 }
317 else {
318 reference.drop();
319 }
320
321 PsiBuilder.Marker precede = qualifiedName.precede();
322 qualifiedName.done(DOT_QUALIFIED_EXPRESSION);
323 qualifiedName = precede;
324 }
325 qualifiedName.drop();
326
327 if (at(DOT)) {
328 advance(); // DOT
329 assert _at(MUL);
330 advance(); // MUL
331 if (at(AS_KEYWORD)) {
332 PsiBuilder.Marker as = mark();
333 advance(); // AS_KEYWORD
334 if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) {
335 as.drop();
336 return;
337 }
338 consumeIf(IDENTIFIER);
339 as.error("Cannot rename all imported items to one identifier");
340 }
341 }
342 if (at(AS_KEYWORD)) {
343 advance(); // AS_KEYWORD
344 if (closeImportWithErrorIfNewline(importDirective, "Expecting identifier")) {
345 return;
346 }
347 expect(IDENTIFIER, "Expecting identifier", TokenSet.create(SEMICOLON));
348 }
349 consumeIf(SEMICOLON);
350 importDirective.done(IMPORT_DIRECTIVE);
351 importDirective.setCustomEdgeTokenBinders(null, TrailingCommentsBinder.INSTANCE$);
352 }
353
354 private boolean closeImportWithErrorIfNewline(PsiBuilder.Marker importDirective, String errorMessage) {
355 if (myBuilder.newlineBeforeCurrentToken()) {
356 error(errorMessage);
357 importDirective.done(IMPORT_DIRECTIVE);
358 return true;
359 }
360 return false;
361 }
362
363 private void parseImportDirectives() {
364 PsiBuilder.Marker importList = mark();
365 if (!at(IMPORT_KEYWORD)) {
366 // this is necessary to allow comments at the start of the file to be bound to the first declaration
367 importList.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null);
368 }
369 while (at(IMPORT_KEYWORD)) {
370 parseImportDirective();
371 }
372 importList.done(IMPORT_LIST);
373 }
374
375 /*
376 * toplevelObject
377 * : package
378 * : class
379 * : extension
380 * : function
381 * : property
382 * : typeAlias
383 * : object
384 * ;
385 */
386 private void parseTopLevelDeclaration() {
387 if (at(SEMICOLON)) {
388 advance(); // SEMICOLON
389 return;
390 }
391 PsiBuilder.Marker decl = mark();
392
393 ModifierDetector detector = new ModifierDetector();
394 parseModifierList(detector, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS);
395
396 IElementType keywordToken = tt();
397 IElementType declType = null;
398 // if (keywordToken == PACKAGE_KEYWORD) {
399 // declType = parsePackageBlock();
400 // }
401 // else
402 if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
403 declType = parseClass(detector.isEnumDetected(), TOP_LEVEL);
404 }
405 else if (keywordToken == FUN_KEYWORD) {
406 declType = parseFunction();
407 }
408 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
409 declType = parseProperty();
410 }
411 else if (keywordToken == TYPE_ALIAS_KEYWORD) {
412 declType = parseTypeAlias();
413 }
414 else if (keywordToken == OBJECT_KEYWORD) {
415 parseObject(NameParsingMode.REQUIRED, true, TOP_LEVEL);
416 declType = OBJECT_DECLARATION;
417 }
418 else if (at(LBRACE)) {
419 error("Expecting a top level declaration");
420 parseBlock();
421 declType = FUN;
422 }
423
424 if (declType == null) {
425 errorAndAdvance("Expecting a top level declaration");
426 decl.drop();
427 }
428 else {
429 closeDeclarationWithCommentBinders(decl, declType, true);
430 }
431 }
432
433 /*
434 * (modifier | annotation)*
435 */
436 boolean parseModifierList(
437 @NotNull AnnotationParsingMode annotationParsingMode
438 ) {
439 return parseModifierList(null, annotationParsingMode);
440 }
441
442 /**
443 * (modifier | annotation)*
444 *
445 * Feeds modifiers (not annotations) into the passed consumer, if it is not null
446 */
447 boolean parseModifierList(
448 @Nullable Consumer<IElementType> tokenConsumer,
449 @NotNull AnnotationParsingMode annotationParsingMode
450 ) {
451 PsiBuilder.Marker list = mark();
452 boolean empty = true;
453 while (!eof()) {
454 if (annotationParsingMode.atMemberStart && atSet(SOFT_KEYWORDS_AT_MEMBER_START)) break;
455 if ((annotationParsingMode == PRIMARY_CONSTRUCTOR_MODIFIER_LIST || annotationParsingMode == PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL) &&
456 atSet(CONSTRUCTOR_KEYWORD, WHERE_KEYWORD)) break;
457
458 if (at(AT)) {
459 if (!tryParseModifier(tokenConsumer)) {
460 parseAnnotationOrList(annotationParsingMode);
461 }
462 }
463 else if (tryParseModifier(tokenConsumer)) {
464 // modifier advanced
465 }
466 else if (annotationParsingMode.allowShortAnnotations && at(IDENTIFIER)) {
467 parseAnnotation(annotationParsingMode);
468 }
469 else {
470 break;
471 }
472 empty = false;
473 }
474 if (empty) {
475 list.drop();
476 }
477 else {
478 list.done(MODIFIER_LIST);
479 }
480 return !empty;
481 }
482
483 private boolean tryParseModifier(@Nullable Consumer<IElementType> tokenConsumer) {
484 PsiBuilder.Marker marker = mark();
485
486 if (at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(1))) {
487 advance(); // AT
488 if (atSet(ANNOTATION_MODIFIERS_KEYWORDS)) {
489 myBuilder.remapCurrentToken(IDENTIFIER);
490 marker.rollbackTo();
491 return false;
492 }
493 }
494
495 if (atSet(MODIFIER_KEYWORDS)) {
496 IElementType tt = tt();
497 if (tokenConsumer != null) {
498 tokenConsumer.consume(tt);
499 }
500 advance(); // MODIFIER
501 marker.collapse(tt);
502 return true;
503 }
504
505 marker.rollbackTo();
506 return false;
507 }
508
509 /*
510 * fileAnnotationList
511 * : ("[" "file:" annotationEntry+ "]")*
512 * ;
513 */
514 private void parseFileAnnotationList(AnnotationParsingMode mode) {
515 if (!mode.isFileAnnotationParsingMode) {
516 LOG.error("expected file annotation parsing mode, but:" + mode);
517 }
518
519 PsiBuilder.Marker fileAnnotationsList = mark();
520
521 if (parseAnnotations(mode)) {
522 fileAnnotationsList.done(FILE_ANNOTATION_LIST);
523 }
524 else {
525 fileAnnotationsList.drop();
526 }
527 }
528
529 /*
530 * annotations
531 * : (annotation | annotationList)*
532 * ;
533 */
534 boolean parseAnnotations(AnnotationParsingMode mode) {
535 if (!parseAnnotationOrList(mode)) return false;
536
537 while (parseAnnotationOrList(mode)) {
538 // do nothing
539 }
540
541 return true;
542 }
543
544 /*
545 * annotation
546 * : annotationPrefix? unescapedAnnotation
547 * ;
548 *
549 * annotationList
550 * : annotationPrefix "[" unescapedAnnotation+ "]"
551 * ;
552 *
553 * annotationUseSiteTarget
554 * : "file"
555 * : "field"
556 * : "property"
557 * : "get"
558 * : "set"
559 * : "param"
560 * : "sparam"
561 * ;
562 *
563 * annotationPrefix:
564 * : ("@" (annotationUseSiteTarget ":")?)
565 * ;
566 */
567 private boolean parseAnnotationOrList(AnnotationParsingMode mode) {
568 if (mode.allowShortAnnotations && at(IDENTIFIER)) {
569 return parseAnnotation(mode);
570 }
571 else if (at(AT)) {
572 IElementType nextRawToken = myBuilder.rawLookup(1);
573 IElementType tokenToMatch = nextRawToken;
574 boolean isTargetedAnnotation = false;
575
576 if ((nextRawToken == IDENTIFIER || ANNOTATION_TARGETS.contains(nextRawToken)) && lookahead(2) == COLON) {
577 tokenToMatch = lookahead(3);
578 isTargetedAnnotation = true;
579 }
580 else if (lookahead(1) == COLON) {
581 // recovery for "@:ann"
582 isTargetedAnnotation = true;
583 tokenToMatch = lookahead(2);
584 }
585
586 if (tokenToMatch == IDENTIFIER) {
587 return parseAnnotation(mode);
588 }
589 else if (tokenToMatch == LBRACKET) {
590 return parseAnnotationList(mode);
591 }
592 else {
593 if (isTargetedAnnotation) {
594 if (lookahead(1) == COLON) {
595 errorAndAdvance("Expected annotation identifier after ':'", 2); // AT, COLON
596 }
597 else {
598 errorAndAdvance("Expected annotation identifier after ':'", 3); // AT, (ANNOTATION TARGET KEYWORD), COLON
599 }
600 }
601 else {
602 errorAndAdvance("Expected annotation identifier after '@'", 1); // AT
603 }
604 }
605 return true;
606 }
607
608 return false;
609 }
610
611 private boolean parseAnnotationList(AnnotationParsingMode mode) {
612 assert _at(AT);
613 PsiBuilder.Marker annotation = mark();
614
615 myBuilder.disableNewlines();
616
617 advance(); // AT
618
619 if (!parseAnnotationTargetIfNeeded(mode)) {
620 annotation.rollbackTo();
621 myBuilder.restoreNewlinesState();
622 return false;
623 }
624
625 assert _at(LBRACKET);
626 advance(); // LBRACKET
627
628 if (!at(IDENTIFIER) && !at(AT)) {
629 error("Expecting a list of annotations");
630 }
631 else {
632 while (at(IDENTIFIER) || at(AT)) {
633 if (at(AT)) {
634 errorAndAdvance("No '@' needed in annotation list"); // AT
635 continue;
636 }
637
638 parseAnnotation(ALLOW_UNESCAPED_REGULAR_ANNOTATIONS);
639 while (at(COMMA)) {
640 errorAndAdvance("No commas needed to separate annotations");
641 }
642 }
643 }
644
645 expect(RBRACKET, "Expecting ']' to close the annotation list");
646 myBuilder.restoreNewlinesState();
647
648 annotation.done(ANNOTATION);
649 return true;
650 }
651
652 // Returns true if we should continue parse annotation
653 private boolean parseAnnotationTargetIfNeeded(AnnotationParsingMode mode) {
654 String expectedAnnotationTargetBeforeColon = "Expected annotation target before ':'";
655
656 if (at(COLON)) {
657 // recovery for "@:ann"
658 errorAndAdvance(expectedAnnotationTargetBeforeColon); // COLON
659 return true;
660 }
661
662 JetKeywordToken targetKeyword = atTargetKeyword();
663 if (mode == FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED && !(targetKeyword == FILE_KEYWORD && lookahead(1) == COLON)) {
664 return false;
665 }
666
667 if (lookahead(1) == COLON && targetKeyword == null && at(IDENTIFIER)) {
668 // recovery for "@fil:ann"
669 errorAndAdvance(expectedAnnotationTargetBeforeColon); // IDENTIFIER
670 advance(); // COLON
671 return true;
672 }
673
674 if (targetKeyword == null && mode.isFileAnnotationParsingMode) {
675 parseAnnotationTarget(mode, FILE_KEYWORD);
676 }
677 else if (targetKeyword != null) {
678 parseAnnotationTarget(mode, targetKeyword);
679 }
680
681 return true;
682 }
683
684 private void parseAnnotationTarget(AnnotationParsingMode mode, JetKeywordToken keyword) {
685 if (keyword == FILE_KEYWORD && !mode.isFileAnnotationParsingMode && at(keyword) && lookahead(1) == COLON) {
686 errorAndAdvance(AT.getValue() + keyword.getValue() + " annotations are only allowed before package declaration", 2);
687 return;
688 }
689
690 String message = "Expecting \"" + keyword.getValue() + COLON.getValue() + "\" prefix for " + keyword.getValue() + " annotations";
691
692 PsiBuilder.Marker marker = mark();
693
694 if (!expect(keyword, message)) {
695 marker.drop();
696 }
697 else {
698 marker.done(ANNOTATION_TARGET);
699 }
700
701 expect(COLON, message, TokenSet.create(IDENTIFIER, RBRACKET, LBRACKET));
702 }
703
704 @Nullable
705 private JetKeywordToken atTargetKeyword() {
706 for (IElementType target : ANNOTATION_TARGETS.getTypes()) {
707 if (at(target)) return (JetKeywordToken) target;
708 }
709 return null;
710 }
711
712 /*
713 * annotation
714 * : annotationPrefix? unescapedAnnotation
715 * ;
716 *
717 * unescapedAnnotation
718 * : SimpleName{"."} typeArguments? valueArguments?
719 * ;
720 */
721 private boolean parseAnnotation(AnnotationParsingMode mode) {
722 assert _at(IDENTIFIER) ||
723 (_at(AT) && !WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(1)));
724
725 PsiBuilder.Marker annotation = mark();
726
727 boolean atAt = at(AT);
728 if (atAt) {
729 advance(); // AT
730 }
731
732 if (atAt && !parseAnnotationTargetIfNeeded(mode)) {
733 annotation.rollbackTo();
734 return false;
735 }
736
737 PsiBuilder.Marker reference = mark();
738 PsiBuilder.Marker typeReference = mark();
739 parseUserType();
740 typeReference.done(TYPE_REFERENCE);
741 reference.done(CONSTRUCTOR_CALLEE);
742
743 parseTypeArgumentList();
744
745 if (at(LPAR)) {
746 myExpressionParsing.parseValueArgumentList();
747 }
748 annotation.done(ANNOTATION_ENTRY);
749
750 return true;
751 }
752
753 public enum NameParsingMode {
754 REQUIRED,
755 ALLOWED,
756 PROHIBITED
757 }
758
759 public enum DeclarationParsingMode {
760 TOP_LEVEL,
761 CLASS_MEMBER,
762 LOCAL
763 }
764
765 /*
766 * class
767 * : modifiers ("class" | "interface") SimpleName
768 * typeParameters?
769 * primaryConstructor?
770 * (":" annotations delegationSpecifier{","})?
771 * typeConstraints
772 * (classBody? | enumClassBody)
773 * ;
774 *
775 * primaryConstructor
776 * : (modifiers "constructor")? ("(" functionParameter{","} ")")
777 * ;
778 *
779 * object
780 * : "object" SimpleName? primaryConstructor? ":" delegationSpecifier{","}? classBody?
781 * ;
782 */
783 IElementType parseClassOrObject(
784 boolean object,
785 NameParsingMode nameParsingMode,
786 boolean optionalBody,
787 boolean enumClass,
788 DeclarationParsingMode declarationParsingMode
789 ) {
790 if (object) {
791 assert _at(OBJECT_KEYWORD);
792 }
793 else {
794 assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD, INTERFACE_KEYWORD);
795 }
796 advance(); // CLASS_KEYWORD, TRAIT_KEYWORD or OBJECT_KEYWORD
797
798 if (nameParsingMode == NameParsingMode.REQUIRED) {
799 OptionalMarker marker = new OptionalMarker(object);
800 expect(IDENTIFIER, "Name expected", CLASS_NAME_RECOVERY_SET);
801 marker.done(OBJECT_DECLARATION_NAME);
802 }
803 else {
804 assert object : "Must be an object to be nameless";
805 if (at(IDENTIFIER)) {
806 if (nameParsingMode == NameParsingMode.PROHIBITED) {
807 errorAndAdvance("An object expression cannot bind a name");
808 }
809 else {
810 assert nameParsingMode == NameParsingMode.ALLOWED;
811 PsiBuilder.Marker marker = mark();
812 advance();
813 marker.done(OBJECT_DECLARATION_NAME);
814 }
815 }
816 }
817
818 OptionalMarker typeParamsMarker = new OptionalMarker(object);
819 boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
820 typeParamsMarker.error("Type parameters are not allowed for objects");
821
822 PsiBuilder.Marker beforeConstructorModifiers = mark();
823 PsiBuilder.Marker primaryConstructorMarker = mark();
824 boolean hasConstructorModifiers = parseModifierList(
825 declarationParsingMode != LOCAL ? PRIMARY_CONSTRUCTOR_MODIFIER_LIST : PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL
826 );
827
828 // Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
829 if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD)) {
830 beforeConstructorModifiers.rollbackTo();
831 return object ? OBJECT_DECLARATION : CLASS;
832 }
833
834 // We are still inside a class declaration
835 beforeConstructorModifiers.drop();
836
837 boolean hasConstructorKeyword = at(CONSTRUCTOR_KEYWORD);
838 if (hasConstructorKeyword) {
839 advance(); // CONSTRUCTOR_KEYWORD
840 }
841
842 if (at(LPAR)) {
843 parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(LBRACE, RBRACE));
844 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR);
845 }
846 else if (hasConstructorModifiers || hasConstructorKeyword) {
847 // A comprehensive error message for cases like:
848 // class A private : Foo
849 // or
850 // class A private {
851 primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR);
852 if (hasConstructorKeyword) {
853 error("Expecting primary constructor parameter list");
854 }
855 else {
856 error("Expecting 'constructor' keyword");
857 }
858 }
859 else {
860 primaryConstructorMarker.drop();
861 }
862
863 if (at(COLON)) {
864 advance(); // COLON
865 parseDelegationSpecifierList();
866 }
867
868 OptionalMarker whereMarker = new OptionalMarker(object);
869 parseTypeConstraintsGuarded(typeParametersDeclared);
870 whereMarker.error("Where clause is not allowed for objects");
871
872 if (at(LBRACE)) {
873 if (enumClass) {
874 parseEnumClassBody();
875 }
876 else {
877 parseClassBody();
878 }
879 }
880 else if (!optionalBody) {
881 PsiBuilder.Marker fakeBody = mark();
882 error("Expecting a class body");
883 fakeBody.done(CLASS_BODY);
884 }
885
886 return object ? OBJECT_DECLARATION : CLASS;
887 }
888
889 IElementType parseClass(boolean enumClass, DeclarationParsingMode declarationParsingMode) {
890 return parseClassOrObject(false, NameParsingMode.REQUIRED, true, enumClass, declarationParsingMode);
891 }
892
893 void parseObject(NameParsingMode nameParsingMode, boolean optionalBody, DeclarationParsingMode declarationParsingMode) {
894 parseClassOrObject(true, nameParsingMode, optionalBody, false, declarationParsingMode);
895 }
896
897 /*
898 * enumClassBody
899 * : "{" enumEntries (";" members)? "}"
900 * ;
901 */
902 private void parseEnumClassBody() {
903 if (!at(LBRACE)) return;
904
905 PsiBuilder.Marker body = mark();
906 myBuilder.enableNewlines();
907
908 advance(); // LBRACE
909
910 if (!parseEnumEntries() && !at(RBRACE)) {
911 error("Expecting ';' after the last enum entry or '}' to close enum class body");
912 }
913 parseMembers();
914 expect(RBRACE, "Expecting '}' to close enum class body");
915
916 myBuilder.restoreNewlinesState();
917 body.done(CLASS_BODY);
918 }
919
920 /**
921 * enumEntries
922 * : enumEntry{","}?
923 * ;
924 *
925 * @return true if enum regular members can follow, false otherwise
926 */
927 private boolean parseEnumEntries() {
928 while (!eof() && !at(RBRACE)) {
929 switch (parseEnumEntry()) {
930 case FAILED:
931 // Special case without any enum entries but with possible members after semicolon
932 if (at(SEMICOLON)) {
933 advance();
934 return true;
935 }
936 else {
937 return false;
938 }
939 case NO_DELIMITER:
940 return false;
941 case COMMA_DELIMITER:
942 break;
943 case SEMICOLON_DELIMITER:
944 return true;
945 }
946 }
947 return false;
948 }
949
950 private enum ParseEnumEntryResult {
951 FAILED,
952 NO_DELIMITER,
953 COMMA_DELIMITER,
954 SEMICOLON_DELIMITER
955 }
956
957 /*
958 * enumEntry
959 * : modifiers SimpleName ("(" arguments ")")? classBody?
960 * ;
961 */
962 private ParseEnumEntryResult parseEnumEntry() {
963 PsiBuilder.Marker entry = mark();
964
965 parseModifierListWithStopAt(TokenSet.create(COMMA, SEMICOLON, RBRACE), ONLY_ESCAPED_REGULAR_ANNOTATIONS);
966
967 if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) {
968 PsiBuilder.Marker nameAsDeclaration = mark();
969 advance(); // IDENTIFIER
970 nameAsDeclaration.done(OBJECT_DECLARATION_NAME);
971
972 if (at(LPAR)) {
973 // Arguments should be parsed here
974 // Also, "fake" constructor call tree is created,
975 // with empty type name inside
976 PsiBuilder.Marker initializerList = mark();
977 PsiBuilder.Marker delegatorSuperCall = mark();
978
979 PsiBuilder.Marker callee = mark();
980 PsiBuilder.Marker typeReference = mark();
981 PsiBuilder.Marker type = mark();
982 PsiBuilder.Marker referenceExpr = mark();
983 referenceExpr.done(ENUM_ENTRY_SUPERCLASS_REFERENCE_EXPRESSION);
984 type.done(USER_TYPE);
985 typeReference.done(TYPE_REFERENCE);
986 callee.done(CONSTRUCTOR_CALLEE);
987
988 myExpressionParsing.parseValueArgumentList();
989 delegatorSuperCall.done(DELEGATOR_SUPER_CALL);
990 initializerList.done(INITIALIZER_LIST);
991 }
992 if (at(LBRACE)) {
993 parseClassBody();
994 }
995 boolean commaFound = at(COMMA);
996 if (commaFound) {
997 advance();
998 }
999 boolean semicolonFound = at(SEMICOLON);
1000 if (semicolonFound) {
1001 advance();
1002 }
1003
1004 // Probably some helper function
1005 closeDeclarationWithCommentBinders(entry, ENUM_ENTRY, true);
1006 return semicolonFound
1007 ? ParseEnumEntryResult.SEMICOLON_DELIMITER
1008 : (commaFound ? ParseEnumEntryResult.COMMA_DELIMITER : ParseEnumEntryResult.NO_DELIMITER);
1009 }
1010 else {
1011 entry.rollbackTo();
1012 return ParseEnumEntryResult.FAILED;
1013 }
1014 }
1015
1016 /*
1017 * classBody
1018 * : ("{" members "}")?
1019 * ;
1020 */
1021 private void parseClassBody() {
1022 PsiBuilder.Marker body = mark();
1023
1024 myBuilder.enableNewlines();
1025
1026 if (expect(LBRACE, "Expecting a class body")) {
1027 parseMembers();
1028 expect(RBRACE, "Missing '}");
1029 }
1030
1031 myBuilder.restoreNewlinesState();
1032
1033 body.done(CLASS_BODY);
1034 }
1035
1036 /**
1037 * members
1038 * : memberDeclaration*
1039 * ;
1040 */
1041 private void parseMembers() {
1042 while (!eof() && !at(RBRACE)) {
1043 parseMemberDeclaration();
1044 }
1045 }
1046
1047 /*
1048 * memberDeclaration
1049 * : modifiers memberDeclaration'
1050 * ;
1051 *
1052 * memberDeclaration'
1053 * : companionObject
1054 * : secondaryConstructor
1055 * : function
1056 * : property
1057 * : class
1058 * : extension
1059 * : typeAlias
1060 * : anonymousInitializer
1061 * : object
1062 * ;
1063 */
1064 private void parseMemberDeclaration() {
1065 if (at(SEMICOLON)) {
1066 advance(); // SEMICOLON
1067 return;
1068 }
1069 PsiBuilder.Marker decl = mark();
1070
1071 ModifierDetector detector = new ModifierDetector();
1072 parseModifierList(detector, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS_AT_MEMBER_MODIFIER_LIST);
1073
1074 IElementType declType = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected());
1075
1076 if (declType == null) {
1077 errorWithRecovery("Expecting member declaration", TokenSet.EMPTY);
1078 decl.drop();
1079 }
1080 else {
1081 closeDeclarationWithCommentBinders(decl, declType, true);
1082 }
1083 }
1084
1085 private IElementType parseMemberDeclarationRest(boolean isEnum, boolean isDefault) {
1086 IElementType keywordToken = tt();
1087 IElementType declType = null;
1088 if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD || keywordToken == INTERFACE_KEYWORD) {
1089 declType = parseClass(isEnum, CLASS_MEMBER);
1090 }
1091 else if (keywordToken == FUN_KEYWORD) {
1092 declType = parseFunction();
1093 }
1094 else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
1095 declType = parseProperty();
1096 }
1097 else if (keywordToken == TYPE_ALIAS_KEYWORD) {
1098 declType = parseTypeAlias();
1099 }
1100 else if (keywordToken == OBJECT_KEYWORD) {
1101 parseObject(isDefault ? NameParsingMode.ALLOWED : NameParsingMode.REQUIRED, true, CLASS_MEMBER);
1102 declType = OBJECT_DECLARATION;
1103 }
1104 else if (at(INIT_KEYWORD)) {
1105 advance(); // init
1106 if (at(LBRACE)) {
1107 parseBlock();
1108 }
1109 else {
1110 mark().error("Expecting '{' after 'init'");
1111 }
1112 declType = ANONYMOUS_INITIALIZER;
1113 }
1114 else if (at(CONSTRUCTOR_KEYWORD)) {
1115 parseSecondaryConstructor();
1116 declType = SECONDARY_CONSTRUCTOR;
1117 }
1118 else if (at(LBRACE)) {
1119 error("Expecting member declaration");
1120 parseBlock();
1121 declType = FUN;
1122 }
1123 return declType;
1124 }
1125
1126 /*
1127 * secondaryConstructor
1128 * : modifiers "constructor" valueParameters (":" constructorDelegationCall)? block
1129 * constructorDelegationCall
1130 * : "this" valueArguments
1131 * : "super" valueArguments
1132 */
1133 private void parseSecondaryConstructor() {
1134 assert _at(CONSTRUCTOR_KEYWORD);
1135
1136 advance(); // CONSTRUCTOR_KEYWORD
1137
1138 TokenSet valueArgsRecoverySet = TokenSet.create(LBRACE, SEMICOLON, RPAR, EOL_OR_SEMICOLON, RBRACE);
1139 if (at(LPAR)) {
1140 parseValueParameterList(false, /*typeRequired = */ true, valueArgsRecoverySet);
1141 }
1142 else {
1143 errorWithRecovery("Expecting '('", TokenSet.orSet(valueArgsRecoverySet, TokenSet.create(COLON)));
1144 }
1145
1146 if (at(COLON)) {
1147 advance(); // COLON
1148
1149 PsiBuilder.Marker delegationCall = mark();
1150
1151 if (at(THIS_KEYWORD) || at(SUPER_KEYWORD)) {
1152 parseThisOrSuper();
1153 myExpressionParsing.parseValueArgumentList();
1154 }
1155 else {
1156 error("Expecting a 'this' or 'super' constructor call");
1157 PsiBuilder.Marker beforeWrongDelegationCallee = null;
1158 if (!at(LPAR)) {
1159 beforeWrongDelegationCallee = mark();
1160 advance(); // wrong delegation callee
1161 }
1162 myExpressionParsing.parseValueArgumentList();
1163
1164 if (beforeWrongDelegationCallee != null) {
1165 if (at(LBRACE)) {
1166 beforeWrongDelegationCallee.drop();
1167 }
1168 else {
1169 beforeWrongDelegationCallee.rollbackTo();
1170 }
1171 }
1172 }
1173
1174 delegationCall.done(CONSTRUCTOR_DELEGATION_CALL);
1175 }
1176 else {
1177 // empty constructor delegation call
1178 PsiBuilder.Marker emptyDelegationCall = mark();
1179 mark().done(CONSTRUCTOR_DELEGATION_REFERENCE);
1180 emptyDelegationCall.done(CONSTRUCTOR_DELEGATION_CALL);
1181 }
1182
1183 if (at(LBRACE)) {
1184 parseBlock();
1185 }
1186 }
1187
1188 private void parseThisOrSuper() {
1189 assert _at(THIS_KEYWORD) || _at(SUPER_KEYWORD);
1190 PsiBuilder.Marker mark = mark();
1191
1192 advance(); // THIS_KEYWORD | SUPER_KEYWORD
1193
1194 mark.done(CONSTRUCTOR_DELEGATION_REFERENCE);
1195 }
1196
1197 /*
1198 * initializer
1199 * : annotations constructorInvocation // type parameters may (must?) be omitted
1200 * ;
1201 */
1202 private void parseInitializer() {
1203 PsiBuilder.Marker initializer = mark();
1204 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
1205
1206 IElementType type;
1207 if (atSet(TYPE_REF_FIRST)) {
1208 PsiBuilder.Marker reference = mark();
1209 parseTypeRef();
1210 reference.done(CONSTRUCTOR_CALLEE);
1211 type = DELEGATOR_SUPER_CALL;
1212 }
1213 else {
1214 errorWithRecovery("Expecting constructor call (<class-name>(...))",
1215 TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, TokenSet.create(RBRACE, LBRACE, COMMA, SEMICOLON)));
1216 initializer.drop();
1217 return;
1218 }
1219 myExpressionParsing.parseValueArgumentList();
1220
1221 initializer.done(type);
1222 }
1223
1224 /*
1225 * typeAlias
1226 * : modifiers "typealias" SimpleName (typeParameters typeConstraints)? "=" type
1227 * ;
1228 */
1229 JetNodeType parseTypeAlias() {
1230 assert _at(TYPE_ALIAS_KEYWORD);
1231
1232 advance(); // TYPE_ALIAS_KEYWORD
1233
1234 expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOP_LEVEL_DECLARATION_FIRST));
1235
1236 if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1237 parseTypeConstraints();
1238 }
1239
1240 expect(EQ, "Expecting '='", TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST, TokenSet.create(SEMICOLON)));
1241
1242 parseTypeRef();
1243
1244 consumeIf(SEMICOLON);
1245
1246 return TYPEDEF;
1247 }
1248
1249 /*
1250 * variableDeclarationEntry
1251 * : SimpleName (":" type)?
1252 * ;
1253 *
1254 * property
1255 * : modifiers ("val" | "var")
1256 * typeParameters? (type "." | annotations)?
1257 * ("(" variableDeclarationEntry{","} ")" | variableDeclarationEntry)
1258 * typeConstraints
1259 * ("by" | "=" expression SEMI?)?
1260 * (getter? setter? | setter? getter?) SEMI?
1261 * ;
1262 */
1263 private IElementType parseProperty() {
1264 return parseProperty(false);
1265 }
1266
1267 public IElementType parseProperty(boolean local) {
1268 if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) {
1269 advance(); // VAL_KEYWORD or VAR_KEYWORD
1270 }
1271 else {
1272 errorAndAdvance("Expecting 'val' or 'var'");
1273 }
1274
1275 boolean typeParametersDeclared = at(LT) && parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
1276
1277 TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, RBRACE, SEMICOLON, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, CLASS_KEYWORD);
1278
1279 myBuilder.disableJoiningComplexTokens();
1280
1281 PsiBuilder.Marker receiver = mark();
1282 boolean receiverTypeDeclared = parseReceiverType("property", propertyNameFollow);
1283
1284 boolean multiDeclaration = at(LPAR);
1285
1286 errorIf(receiver, multiDeclaration && receiverTypeDeclared, "Receiver type is not allowed on a multi-declaration");
1287
1288 if (multiDeclaration) {
1289 PsiBuilder.Marker multiDecl = mark();
1290 parseMultiDeclarationName(propertyNameFollow);
1291 errorIf(multiDecl, !local, "Multi-declarations are only allowed for local variables/values");
1292 }
1293 else {
1294 parseFunctionOrPropertyName(receiverTypeDeclared, "property", propertyNameFollow, /*nameRequired = */ false);
1295 }
1296
1297 myBuilder.restoreJoiningComplexTokensState();
1298
1299 if (at(COLON)) {
1300 PsiBuilder.Marker type = mark();
1301 advance(); // COLON
1302 parseTypeRef();
1303 errorIf(type, multiDeclaration, "Type annotations are not allowed on multi-declarations");
1304 }
1305
1306 parseTypeConstraintsGuarded(typeParametersDeclared);
1307
1308 if (local) {
1309 if (at(BY_KEYWORD)) {
1310 parsePropertyDelegate();
1311 }
1312 else if (at(EQ)) {
1313 advance(); // EQ
1314 myExpressionParsing.parseExpression();
1315 // "val a = 1; b" must not be an infix call of b on "val ...;"
1316 }
1317 }
1318 else {
1319 if (at(BY_KEYWORD)) {
1320 parsePropertyDelegate();
1321 consumeIf(SEMICOLON);
1322 }
1323 else if (at(EQ)) {
1324 advance(); // EQ
1325 myExpressionParsing.parseExpression();
1326 consumeIf(SEMICOLON);
1327 }
1328
1329 if (parsePropertyGetterOrSetter()) {
1330 parsePropertyGetterOrSetter();
1331 }
1332 if (!atSet(EOL_OR_SEMICOLON, RBRACE)) {
1333 if (getLastToken() != SEMICOLON) {
1334 errorUntil("Property getter or setter expected", TokenSet.create(EOL_OR_SEMICOLON, LBRACE, RBRACE));
1335 }
1336 }
1337 else {
1338 consumeIf(SEMICOLON);
1339 }
1340 }
1341
1342 return multiDeclaration ? MULTI_VARIABLE_DECLARATION : PROPERTY;
1343 }
1344
1345 /*
1346 * propertyDelegate
1347 * : "by" expression
1348 * ;
1349 */
1350 private void parsePropertyDelegate() {
1351 assert _at(BY_KEYWORD);
1352 PsiBuilder.Marker delegate = mark();
1353 advance(); // BY_KEYWORD
1354 myExpressionParsing.parseExpression();
1355 delegate.done(PROPERTY_DELEGATE);
1356 }
1357
1358 /*
1359 * (SimpleName (":" type)){","}
1360 */
1361 public void parseMultiDeclarationName(TokenSet follow) {
1362 // Parsing multi-name, e.g.
1363 // val (a, b) = foo()
1364 myBuilder.disableNewlines();
1365 advance(); // LPAR
1366
1367 TokenSet recoverySet = TokenSet.orSet(PARAMETER_NAME_RECOVERY_SET, follow);
1368 if (!atSet(follow)) {
1369 while (true) {
1370 if (at(COMMA)) {
1371 errorAndAdvance("Expecting a name");
1372 }
1373 else if (at(RPAR)) {
1374 error("Expecting a name");
1375 break;
1376 }
1377 PsiBuilder.Marker property = mark();
1378
1379 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, RPAR, COLON, IN_KEYWORD, EQ));
1380
1381 expect(IDENTIFIER, "Expecting a name", recoverySet);
1382
1383 if (at(COLON)) {
1384 advance(); // COLON
1385 parseTypeRef(follow);
1386 }
1387 property.done(MULTI_VARIABLE_DECLARATION_ENTRY);
1388
1389 if (!at(COMMA)) break;
1390 advance(); // COMMA
1391 }
1392 }
1393
1394 expect(RPAR, "Expecting ')'", follow);
1395 myBuilder.restoreNewlinesState();
1396 }
1397
1398 /*
1399 * getterOrSetter
1400 * : modifiers ("get" | "set")
1401 * :
1402 * ( "get" "(" ")"
1403 * |
1404 * "set" "(" modifiers parameter ")"
1405 * ) functionBody
1406 * ;
1407 */
1408 private boolean parsePropertyGetterOrSetter() {
1409 PsiBuilder.Marker getterOrSetter = mark();
1410
1411 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
1412
1413 if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
1414 getterOrSetter.rollbackTo();
1415 return false;
1416 }
1417
1418 boolean setter = at(SET_KEYWORD);
1419 advance(); // GET_KEYWORD or SET_KEYWORD
1420
1421 if (!at(LPAR)) {
1422 // Account for Jet-114 (val a : int get {...})
1423 TokenSet ACCESSOR_FIRST_OR_PROPERTY_END = TokenSet.orSet(MODIFIER_KEYWORDS, TokenSet.create(AT, GET_KEYWORD, SET_KEYWORD, EOL_OR_SEMICOLON, RBRACE));
1424 if (!atSet(ACCESSOR_FIRST_OR_PROPERTY_END)) {
1425 errorUntil("Accessor body expected", TokenSet.orSet(ACCESSOR_FIRST_OR_PROPERTY_END, TokenSet.create(LBRACE, LPAR, EQ)));
1426 }
1427 else {
1428 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false);
1429 return true;
1430 }
1431 }
1432
1433 myBuilder.disableNewlines();
1434 expect(LPAR, "Expecting '('", TokenSet.create(RPAR, IDENTIFIER, COLON, LBRACE, EQ));
1435 if (setter) {
1436 PsiBuilder.Marker parameterList = mark();
1437 PsiBuilder.Marker setterParameter = mark();
1438 parseModifierListWithUnescapedAnnotations(TokenSet.create(RPAR, COMMA, COLON));
1439 expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
1440
1441 if (at(COLON)) {
1442 advance(); // COLON
1443 parseTypeRef();
1444 }
1445 setterParameter.done(VALUE_PARAMETER);
1446 parameterList.done(VALUE_PARAMETER_LIST);
1447 }
1448 if (!at(RPAR)) {
1449 errorUntil("Expecting ')'", TokenSet.create(RPAR, COLON, LBRACE, RBRACE, EQ, EOL_OR_SEMICOLON));
1450 }
1451 if (at(RPAR)) {
1452 advance();
1453 }
1454 myBuilder.restoreNewlinesState();
1455
1456 if (at(COLON)) {
1457 advance();
1458
1459 parseTypeRef();
1460 }
1461
1462 parseFunctionBody();
1463
1464 closeDeclarationWithCommentBinders(getterOrSetter, PROPERTY_ACCESSOR, false);
1465
1466 return true;
1467 }
1468
1469 /*
1470 * function
1471 * : modifiers "fun" typeParameters?
1472 * (type "." | annotations)?
1473 * SimpleName
1474 * typeParameters? functionParameters (":" type)?
1475 * typeConstraints
1476 * functionBody?
1477 * ;
1478 */
1479 IElementType parseFunction() {
1480 assert _at(FUN_KEYWORD);
1481
1482 advance(); // FUN_KEYWORD
1483
1484 // Recovery for the case of class A { fun| }
1485 if (at(RBRACE)) {
1486 error("Function body expected");
1487 return FUN;
1488 }
1489
1490 boolean typeParameterListOccurred = false;
1491 if (at(LT)) {
1492 parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, RBRACE, LPAR));
1493 typeParameterListOccurred = true;
1494 }
1495
1496 myBuilder.disableJoiningComplexTokens();
1497
1498 TokenSet functionNameFollow = TokenSet.create(LT, LPAR, RPAR, COLON, EQ);
1499 boolean receiverFound = parseReceiverType("function", functionNameFollow);
1500
1501 // function as expression has no name
1502 parseFunctionOrPropertyName(receiverFound, "function", functionNameFollow, /*nameRequired = */ true);
1503
1504 myBuilder.restoreJoiningComplexTokensState();
1505
1506 TokenSet valueParametersFollow = TokenSet.create(EQ, LBRACE, RBRACE, SEMICOLON, RPAR);
1507
1508 if (at(LT)) {
1509 PsiBuilder.Marker error = mark();
1510 parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
1511 errorIf(error, typeParameterListOccurred, "Only one type parameter list is allowed for a function");
1512 typeParameterListOccurred = true;
1513 }
1514
1515 if (at(LPAR)) {
1516 parseValueParameterList(false, /* typeRequired = */ false, valueParametersFollow);
1517 }
1518 else {
1519 error("Expecting '('");
1520 }
1521
1522 if (at(COLON)) {
1523 advance(); // COLON
1524
1525 parseTypeRef();
1526 }
1527
1528 parseTypeConstraintsGuarded(typeParameterListOccurred);
1529
1530 if (at(SEMICOLON)) {
1531 advance(); // SEMICOLON
1532 }
1533 else if (at(EQ) || at(LBRACE)) {
1534 parseFunctionBody();
1535 }
1536
1537 return FUN;
1538 }
1539
1540 /*
1541 * (type "." | annotations)?
1542 */
1543 private boolean parseReceiverType(String title, TokenSet nameFollow) {
1544 PsiBuilder.Marker annotations = mark();
1545 boolean annotationsPresent = parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
1546 int lastDot = lastDotAfterReceiver();
1547 boolean receiverPresent = lastDot != -1;
1548 if (annotationsPresent) {
1549 if (receiverPresent) {
1550 annotations.rollbackTo();
1551 }
1552 else {
1553 annotations.error("Annotations are not allowed in this position");
1554 }
1555 }
1556 else {
1557 annotations.drop();
1558 }
1559
1560 if (!receiverPresent) return false;
1561
1562 createTruncatedBuilder(lastDot).parseTypeRef();
1563
1564 if (atSet(RECEIVER_TYPE_TERMINATORS)) {
1565 advance(); // expectation
1566 }
1567 else {
1568 errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow);
1569 }
1570 return true;
1571 }
1572
1573 private int lastDotAfterReceiver() {
1574 if (at(LPAR)) {
1575 return matchTokenStreamPredicate(
1576 new FirstBefore(
1577 new AtSet(RECEIVER_TYPE_TERMINATORS),
1578 new AbstractTokenStreamPredicate() {
1579 @Override
1580 public boolean matching(boolean topLevel) {
1581 if (topLevel && definitelyOutOfReceiver()) {
1582 return true;
1583 }
1584 return topLevel && !at(QUEST) && !at(LPAR) && !at(RPAR);
1585 }
1586 }
1587 ));
1588 }
1589 else {
1590 return matchTokenStreamPredicate(
1591 new LastBefore(
1592 new AtSet(RECEIVER_TYPE_TERMINATORS),
1593 new AbstractTokenStreamPredicate() {
1594 @Override
1595 public boolean matching(boolean topLevel) {
1596 if (topLevel && (definitelyOutOfReceiver() || at(LPAR))) return true;
1597 if (topLevel && at(IDENTIFIER)) {
1598 IElementType lookahead = lookahead(1);
1599 return lookahead != LT && lookahead != DOT && lookahead != SAFE_ACCESS && lookahead != QUEST;
1600 }
1601 return false;
1602 }
1603 }));
1604 }
1605 }
1606
1607 private boolean definitelyOutOfReceiver() {
1608 return atSet(EQ, COLON, LBRACE, RBRACE, BY_KEYWORD) || atSet(TOP_LEVEL_DECLARATION_FIRST);
1609 }
1610
1611 /*
1612 * IDENTIFIER
1613 */
1614 private void parseFunctionOrPropertyName(boolean receiverFound, String title, TokenSet nameFollow, boolean nameRequired) {
1615 if (nameRequired && atSet(nameFollow)) return; // no name
1616
1617 TokenSet recoverySet = TokenSet.orSet(nameFollow, TokenSet.create(LBRACE, RBRACE));
1618 if (!receiverFound) {
1619 expect(IDENTIFIER, "Expecting " + title + " name or receiver type", recoverySet);
1620 }
1621 else {
1622 expect(IDENTIFIER, "Expecting " + title + " name", recoverySet);
1623 }
1624 }
1625
1626 /*
1627 * functionBody
1628 * : block
1629 * : "=" element
1630 * ;
1631 */
1632 private void parseFunctionBody() {
1633 if (at(LBRACE)) {
1634 parseBlock();
1635 }
1636 else if (at(EQ)) {
1637 advance(); // EQ
1638 myExpressionParsing.parseExpression();
1639 consumeIf(SEMICOLON);
1640 }
1641 else {
1642 error("Expecting function body");
1643 }
1644 }
1645
1646 /*
1647 * block
1648 * : "{" (expressions)* "}"
1649 * ;
1650 */
1651 void parseBlock() {
1652 PsiBuilder.Marker block = mark();
1653
1654 myBuilder.enableNewlines();
1655 expect(LBRACE, "Expecting '{' to open a block");
1656
1657 myExpressionParsing.parseStatements();
1658
1659 expect(RBRACE, "Expecting '}'");
1660 myBuilder.restoreNewlinesState();
1661
1662 block.done(BLOCK);
1663 }
1664
1665 /*
1666 * delegationSpecifier{","}
1667 */
1668 /*package*/ void parseDelegationSpecifierList() {
1669 PsiBuilder.Marker list = mark();
1670
1671 while (true) {
1672 if (at(COMMA)) {
1673 errorAndAdvance("Expecting a delegation specifier");
1674 continue;
1675 }
1676 parseDelegationSpecifier();
1677 if (!at(COMMA)) break;
1678 advance(); // COMMA
1679 }
1680
1681 list.done(DELEGATION_SPECIFIER_LIST);
1682 }
1683
1684 /*
1685 * delegationSpecifier
1686 * : constructorInvocation // type and constructor arguments
1687 * : userType
1688 * : explicitDelegation
1689 * ;
1690 *
1691 * explicitDelegation
1692 * : userType "by" element
1693 * ;
1694 */
1695 private void parseDelegationSpecifier() {
1696 PsiBuilder.Marker delegator = mark();
1697 PsiBuilder.Marker reference = mark();
1698 parseTypeRef();
1699
1700 if (at(BY_KEYWORD)) {
1701 reference.drop();
1702 advance(); // BY_KEYWORD
1703 createForByClause(myBuilder).myExpressionParsing.parseExpression();
1704 delegator.done(DELEGATOR_BY);
1705 }
1706 else if (at(LPAR)) {
1707 reference.done(CONSTRUCTOR_CALLEE);
1708 myExpressionParsing.parseValueArgumentList();
1709 delegator.done(DELEGATOR_SUPER_CALL);
1710 }
1711 else {
1712 reference.drop();
1713 delegator.done(DELEGATOR_SUPER_CLASS);
1714 }
1715 }
1716
1717 /*
1718 * typeParameters
1719 * : ("<" typeParameter{","} ">"
1720 * ;
1721 */
1722 private boolean parseTypeParameterList(TokenSet recoverySet) {
1723 boolean result = false;
1724 if (at(LT)) {
1725 PsiBuilder.Marker list = mark();
1726
1727 myBuilder.disableNewlines();
1728 advance(); // LT
1729
1730 while (true) {
1731 if (at(COMMA)) errorAndAdvance("Expecting type parameter declaration");
1732 parseTypeParameter();
1733
1734 if (!at(COMMA)) break;
1735 advance(); // COMMA
1736 }
1737
1738 expect(GT, "Missing '>'", recoverySet);
1739 myBuilder.restoreNewlinesState();
1740 result = true;
1741
1742 list.done(TYPE_PARAMETER_LIST);
1743 }
1744 return result;
1745 }
1746
1747 /*
1748 * typeConstraints
1749 * : ("where" typeConstraint{","})?
1750 * ;
1751 */
1752 private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
1753 PsiBuilder.Marker error = mark();
1754 boolean constraints = parseTypeConstraints();
1755 errorIf(error, constraints && !typeParameterListOccurred, "Type constraints are not allowed when no type parameters declared");
1756 }
1757
1758 private boolean parseTypeConstraints() {
1759 if (at(WHERE_KEYWORD)) {
1760 parseTypeConstraintList();
1761 return true;
1762 }
1763 return false;
1764 }
1765
1766 /*
1767 * typeConstraint{","}
1768 */
1769 private void parseTypeConstraintList() {
1770 assert _at(WHERE_KEYWORD);
1771
1772 advance(); // WHERE_KEYWORD
1773
1774 PsiBuilder.Marker list = mark();
1775
1776 while (true) {
1777 if (at(COMMA)) errorAndAdvance("Type constraint expected");
1778 parseTypeConstraint();
1779 if (!at(COMMA)) break;
1780 advance(); // COMMA
1781 }
1782
1783 list.done(TYPE_CONSTRAINT_LIST);
1784 }
1785
1786 /*
1787 * typeConstraint
1788 * : annotations SimpleName ":" type
1789 * ;
1790 */
1791 private void parseTypeConstraint() {
1792 PsiBuilder.Marker constraint = mark();
1793
1794 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
1795
1796 PsiBuilder.Marker reference = mark();
1797 if (expect(IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA, LBRACE, RBRACE), TYPE_REF_FIRST))) {
1798 reference.done(REFERENCE_EXPRESSION);
1799 }
1800 else {
1801 reference.drop();
1802 }
1803
1804 expect(COLON, "Expecting ':' before the upper bound", TokenSet.orSet(TokenSet.create(LBRACE, RBRACE), TYPE_REF_FIRST));
1805
1806 parseTypeRef();
1807
1808 constraint.done(TYPE_CONSTRAINT);
1809 }
1810
1811 /*
1812 * typeParameter
1813 * : modifiers SimpleName (":" userType)?
1814 * ;
1815 */
1816 private void parseTypeParameter() {
1817 if (atSet(TYPE_PARAMETER_GT_RECOVERY_SET)) {
1818 error("Type parameter declaration expected");
1819 return;
1820 }
1821
1822 PsiBuilder.Marker mark = mark();
1823
1824 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, GT, COLON));
1825
1826 expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
1827
1828 if (at(COLON)) {
1829 advance(); // COLON
1830 parseTypeRef();
1831 }
1832
1833 mark.done(TYPE_PARAMETER);
1834
1835 }
1836
1837 /*
1838 * type
1839 * : annotations typeDescriptor
1840 *
1841 * typeDescriptor
1842 * : selfType
1843 * : functionType
1844 * : userType
1845 * : nullableType
1846 * : "dynamic"
1847 * ;
1848 *
1849 * nullableType
1850 * : typeDescriptor "?"
1851 */
1852 void parseTypeRef() {
1853 parseTypeRef(TokenSet.EMPTY);
1854 }
1855
1856 void parseTypeRef(TokenSet extraRecoverySet) {
1857 PsiBuilder.Marker typeRefMarker = parseTypeRefContents(extraRecoverySet);
1858 typeRefMarker.done(TYPE_REFERENCE);
1859 }
1860
1861 // The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should stop
1862 // on expression-indicating symbols or not
1863 private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) {
1864 PsiBuilder.Marker typeRefMarker = mark();
1865 parseAnnotations(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
1866
1867 IElementType lookahead = lookahead(1);
1868 IElementType lookahead2 = lookahead(2);
1869 boolean typeBeforeDot = true;
1870 if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
1871 PsiBuilder.Marker dynamicType = mark();
1872 advance(); // DYNAMIC_KEYWORD
1873 dynamicType.done(DYNAMIC_TYPE);
1874 }
1875 else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
1876 parseUserType();
1877 }
1878 else if (at(LPAR)) {
1879 PsiBuilder.Marker functionOrParenthesizedType = mark();
1880
1881 // This may be a function parameter list or just a prenthesized type
1882 advance(); // LPAR
1883 parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
1884
1885 if (at(RPAR)) {
1886 advance(); // RPAR
1887 if (at(ARROW)) {
1888 // It's a function type with one parameter specified
1889 // (A) -> B
1890 functionOrParenthesizedType.rollbackTo();
1891 parseFunctionType();
1892 }
1893 else {
1894 // It's a parenthesized type
1895 // (A)
1896 functionOrParenthesizedType.drop();
1897 }
1898 }
1899 else {
1900 // This must be a function type
1901 // (A, B) -> C
1902 // or
1903 // (a : A) -> C
1904 functionOrParenthesizedType.rollbackTo();
1905 parseFunctionType();
1906 }
1907
1908 }
1909 else if (at(CAPITALIZED_THIS_KEYWORD)) {
1910 parseSelfType();
1911 }
1912 else {
1913 errorWithRecovery("Type expected",
1914 TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST,
1915 TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON),
1916 extraRecoverySet));
1917 typeBeforeDot = false;
1918 }
1919
1920 // Disabling token merge is required for cases like
1921 // Int?.(Foo) -> Bar
1922 myBuilder.disableJoiningComplexTokens();
1923 typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
1924 myBuilder.restoreJoiningComplexTokensState();
1925
1926 if (typeBeforeDot && at(DOT)) {
1927 // This is a receiver for a function type
1928 // A.(B) -> C
1929 // ^
1930
1931 PsiBuilder.Marker functionType = typeRefMarker.precede();
1932 PsiBuilder.Marker receiverType = typeRefMarker.precede();
1933 typeRefMarker.done(TYPE_REFERENCE);
1934 receiverType.done(FUNCTION_TYPE_RECEIVER);
1935
1936 advance(); // DOT
1937
1938 if (at(LPAR)) {
1939 parseFunctionTypeContents().drop();
1940 }
1941 else {
1942 error("Expecting function type");
1943 }
1944 typeRefMarker = functionType.precede();
1945
1946 functionType.done(FUNCTION_TYPE);
1947 }
1948
1949 return typeRefMarker;
1950 }
1951
1952 @NotNull
1953 PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
1954 // ?: is joined regardless of joining state
1955 while (at(QUEST) && myBuilder.rawLookup(1) != COLON) {
1956 PsiBuilder.Marker precede = typeRefMarker.precede();
1957 advance(); // QUEST
1958 typeRefMarker.done(NULLABLE_TYPE);
1959 typeRefMarker = precede;
1960 }
1961 return typeRefMarker;
1962 }
1963
1964 /*
1965 * userType
1966 * : ("package" ".")? simpleUserType{"."}
1967 * ;
1968 *
1969 * recovers on platform types:
1970 * - Foo!
1971 * - (Mutable)List<Foo>!
1972 * - Array<(out) Foo>!
1973 */
1974 void parseUserType() {
1975 PsiBuilder.Marker userType = mark();
1976
1977 if (at(PACKAGE_KEYWORD)) {
1978 advance(); // PACKAGE_KEYWORD
1979 expect(DOT, "Expecting '.'", TokenSet.create(IDENTIFIER, LBRACE, RBRACE));
1980 }
1981
1982 PsiBuilder.Marker reference = mark();
1983 while (true) {
1984 recoverOnParenthesizedWordForPlatformTypes(0, "Mutable", true);
1985
1986 if (expect(IDENTIFIER, "Expecting type name",
1987 TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW, DECLARATION_FIRST))) {
1988 reference.done(REFERENCE_EXPRESSION);
1989 }
1990 else {
1991 reference.drop();
1992 break;
1993 }
1994
1995 parseTypeArgumentList();
1996
1997 recoverOnPlatformTypeSuffix();
1998
1999 if (!at(DOT)) {
2000 break;
2001 }
2002 if (lookahead(1) == LPAR && !atParenthesizedMutableForPlatformTypes(1)) {
2003 // This may be a receiver for a function type
2004 // Int.(Int) -> Int
2005 break;
2006 }
2007
2008 PsiBuilder.Marker precede = userType.precede();
2009 userType.done(USER_TYPE);
2010 userType = precede;
2011
2012 advance(); // DOT
2013 reference = mark();
2014 }
2015
2016 userType.done(USER_TYPE);
2017 }
2018
2019 private boolean atParenthesizedMutableForPlatformTypes(int offset) {
2020 return recoverOnParenthesizedWordForPlatformTypes(offset, "Mutable", false);
2021 }
2022
2023 private boolean recoverOnParenthesizedWordForPlatformTypes(int offset, String word, boolean consume) {
2024 // Array<(out) Foo>! or (Mutable)List<Bar>!
2025 if (lookahead(offset) == LPAR && lookahead(offset + 1) == IDENTIFIER && lookahead(offset + 2) == RPAR && lookahead(offset + 3) == IDENTIFIER) {
2026 PsiBuilder.Marker error = mark();
2027
2028 advance(offset);
2029
2030 advance(); // LPAR
2031 if (!word.equals(myBuilder.getTokenText())) {
2032 // something other than "out" / "Mutable"
2033 error.rollbackTo();
2034 return false;
2035 }
2036 else {
2037 advance(); // IDENTIFIER('out')
2038 advance(); // RPAR
2039
2040 if (consume) {
2041 error.error("Unexpected tokens");
2042 }
2043 else {
2044 error.rollbackTo();
2045 }
2046
2047 return true;
2048 }
2049 }
2050 return false;
2051 }
2052
2053 private void recoverOnPlatformTypeSuffix() {
2054 // Recovery for platform types
2055 if (at(EXCL)) {
2056 PsiBuilder.Marker error = mark();
2057 advance(); // EXCL
2058 error.error("Unexpected token");
2059 }
2060 }
2061
2062 /*
2063 * selfType
2064 * : "This"
2065 * ;
2066 */
2067 private void parseSelfType() {
2068 assert _at(CAPITALIZED_THIS_KEYWORD);
2069
2070 PsiBuilder.Marker type = mark();
2071 advance(); // CAPITALIZED_THIS_KEYWORD
2072 type.done(SELF_TYPE);
2073 }
2074
2075 /*
2076 * (optionalProjection type){","}
2077 */
2078 private PsiBuilder.Marker parseTypeArgumentList() {
2079 if (!at(LT)) return null;
2080
2081 PsiBuilder.Marker list = mark();
2082
2083 tryParseTypeArgumentList(TokenSet.EMPTY);
2084
2085 list.done(TYPE_ARGUMENT_LIST);
2086 return list;
2087 }
2088
2089 boolean tryParseTypeArgumentList(TokenSet extraRecoverySet) {
2090 myBuilder.disableNewlines();
2091 advance(); // LT
2092
2093 while (true) {
2094 PsiBuilder.Marker projection = mark();
2095
2096 recoverOnParenthesizedWordForPlatformTypes(0, "out", true);
2097
2098 // TokenSet lookFor = TokenSet.create(IDENTIFIER);
2099 // TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
2100 // parseModifierListWithUnescapedAnnotations(MODIFIER_LIST, lookFor, stopAt);
2101 // Currently we do not allow annotations
2102 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS);
2103
2104 if (at(MUL)) {
2105 advance(); // MUL
2106 }
2107 else {
2108 parseTypeRef(extraRecoverySet);
2109 }
2110 projection.done(TYPE_PROJECTION);
2111 if (!at(COMMA)) break;
2112 advance(); // COMMA
2113 }
2114
2115 boolean atGT = at(GT);
2116 if (!atGT) {
2117 error("Expecting a '>'");
2118 }
2119 else {
2120 advance(); // GT
2121 }
2122 myBuilder.restoreNewlinesState();
2123 return atGT;
2124 }
2125
2126 public void parseModifierListWithUnescapedAnnotations(TokenSet stopAt) {
2127 parseModifierListWithLookForStopAt(TokenSet.create(IDENTIFIER), stopAt, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS);
2128 }
2129
2130 public void parseModifierListWithStopAt(TokenSet stopAt, AnnotationParsingMode mode) {
2131 parseModifierListWithLookForStopAt(TokenSet.create(IDENTIFIER), stopAt, mode);
2132 }
2133
2134 public void parseModifierListWithUnescapedAnnotations(TokenSet lookFor, TokenSet stopAt) {
2135 parseModifierListWithLookForStopAt(lookFor, stopAt, ALLOW_UNESCAPED_REGULAR_ANNOTATIONS);
2136 }
2137
2138 public void parseModifierListWithLookForStopAt(TokenSet lookFor, TokenSet stopAt, AnnotationParsingMode mode) {
2139 int lastId = matchTokenStreamPredicate(new LastBefore(new AtSet(lookFor), new AnnotationTargetStop(stopAt, ANNOTATION_TARGETS), false));
2140 createTruncatedBuilder(lastId).parseModifierList(mode);
2141 }
2142
2143 private class AnnotationTargetStop extends AbstractTokenStreamPredicate {
2144 private final TokenSet stopAt;
2145 private final TokenSet annotationTargets;
2146
2147 private IElementType previousToken;
2148 private IElementType tokenBeforePrevious;
2149
2150 public AnnotationTargetStop(TokenSet stopAt, TokenSet annotationTargets) {
2151 this.stopAt = stopAt;
2152 this.annotationTargets = annotationTargets;
2153 }
2154
2155 @Override
2156 public boolean matching(boolean topLevel) {
2157 if (atSet(stopAt)) return true;
2158
2159 if (at(COLON) && !(tokenBeforePrevious == AT && (previousToken == IDENTIFIER || annotationTargets.contains(previousToken)))) {
2160 return true;
2161 }
2162
2163 tokenBeforePrevious = previousToken;
2164 previousToken = tt();
2165
2166 return false;
2167 }
2168 }
2169
2170 /*
2171 * functionType
2172 * : "(" (parameter | modifiers type){","}? ")" "->" type?
2173 * ;
2174 */
2175 private void parseFunctionType() {
2176 parseFunctionTypeContents().done(FUNCTION_TYPE);
2177 }
2178
2179 private PsiBuilder.Marker parseFunctionTypeContents() {
2180 assert _at(LPAR) : tt();
2181 PsiBuilder.Marker functionType = mark();
2182
2183 parseValueParameterList(true, /* typeRequired = */ true, TokenSet.EMPTY);
2184
2185 expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST);
2186 parseTypeRef();
2187
2188 return functionType;
2189 }
2190
2191 /*
2192 * functionParameters
2193 * : "(" functionParameter{","}? ")" // default values
2194 * ;
2195 *
2196 * functionParameter
2197 * : modifiers functionParameterRest
2198 * ;
2199 *
2200 * functionParameterRest
2201 * : parameter ("=" element)?
2202 * ;
2203 */
2204 void parseValueParameterList(boolean isFunctionTypeContents, boolean typeRequired, TokenSet recoverySet) {
2205 assert _at(LPAR);
2206 PsiBuilder.Marker parameters = mark();
2207
2208 myBuilder.disableNewlines();
2209 advance(); // LPAR
2210
2211 if (!at(RPAR) && !atSet(recoverySet)) {
2212 while (true) {
2213 if (at(COMMA)) {
2214 errorAndAdvance("Expecting a parameter declaration");
2215 }
2216 else if (at(RPAR)) {
2217 error("Expecting a parameter declaration");
2218 break;
2219 }
2220
2221 if (isFunctionTypeContents) {
2222 if (!tryParseValueParameter(typeRequired)) {
2223 PsiBuilder.Marker valueParameter = mark();
2224 parseModifierList(ONLY_ESCAPED_REGULAR_ANNOTATIONS); // lazy, out, ref
2225 parseTypeRef();
2226 closeDeclarationWithCommentBinders(valueParameter, VALUE_PARAMETER, false);
2227 }
2228 }
2229 else {
2230 parseValueParameter(typeRequired);
2231 }
2232
2233 if (at(COMMA)) {
2234 advance(); // COMMA
2235 }
2236 else {
2237 if (!at(RPAR)) error("Expecting comma or ')'");
2238 if (!atSet(isFunctionTypeContents ? LAMBDA_VALUE_PARAMETER_FIRST : VALUE_PARAMETER_FIRST)) break;
2239 }
2240 }
2241 }
2242
2243 expect(RPAR, "Expecting ')'", recoverySet);
2244 myBuilder.restoreNewlinesState();
2245
2246 parameters.done(VALUE_PARAMETER_LIST);
2247 }
2248
2249 /*
2250 * functionParameter
2251 * : modifiers ("val" | "var")? parameter ("=" element)?
2252 * ;
2253 */
2254 private boolean tryParseValueParameter(boolean typeRequired) {
2255 return parseValueParameter(true, typeRequired);
2256 }
2257
2258 public void parseValueParameter(boolean typeRequired) {
2259 parseValueParameter(false, typeRequired);
2260 }
2261
2262 private boolean parseValueParameter(boolean rollbackOnFailure, boolean typeRequired) {
2263 PsiBuilder.Marker parameter = mark();
2264
2265 parseModifierListWithUnescapedAnnotations(TokenSet.create(COMMA, RPAR));
2266
2267 if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
2268 advance(); // VAR_KEYWORD | VAL_KEYWORD
2269 }
2270
2271 if (!parseFunctionParameterRest(typeRequired) && rollbackOnFailure) {
2272 parameter.rollbackTo();
2273 return false;
2274 }
2275
2276 closeDeclarationWithCommentBinders(parameter, VALUE_PARAMETER, false);
2277 return true;
2278 }
2279
2280 /*
2281 * functionParameterRest
2282 * : parameter ("=" element)?
2283 * ;
2284 */
2285 private boolean parseFunctionParameterRest(boolean typeRequired) {
2286 boolean noErrors = true;
2287
2288 // Recovery for the case 'fun foo(Array<String>) {}'
2289 // Recovery for the case 'fun foo(: Int) {}'
2290 if ((at(IDENTIFIER) && lookahead(1) == LT) || at(COLON)) {
2291 error("Parameter name expected");
2292 if (at(COLON)) {
2293 // We keep noErrors == true so that unnamed parameters starting with ":" are not rolled back during parsing of functional types
2294 advance(); // COLON
2295 }
2296 else {
2297 noErrors = false;
2298 }
2299 parseTypeRef();
2300 }
2301 else {
2302 expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
2303
2304 if (at(COLON)) {
2305 advance(); // COLON
2306 parseTypeRef();
2307 }
2308 else if (typeRequired) {
2309 errorWithRecovery("Parameters must have type annotation", PARAMETER_NAME_RECOVERY_SET);
2310 noErrors = false;
2311 }
2312 }
2313
2314 if (at(EQ)) {
2315 advance(); // EQ
2316 myExpressionParsing.parseExpression();
2317 }
2318
2319 return noErrors;
2320 }
2321
2322 @Override
2323 protected JetParsing create(SemanticWhitespaceAwarePsiBuilder builder) {
2324 return createForTopLevel(builder);
2325 }
2326
2327 /*package*/ static class ModifierDetector implements Consumer<IElementType> {
2328 private boolean enumDetected = false;
2329 private boolean defaultDetected = false;
2330
2331 @Override
2332 public void consume(IElementType item) {
2333 if (item == JetTokens.ENUM_KEYWORD) {
2334 enumDetected = true;
2335 }
2336 else if (item == JetTokens.COMPANION_KEYWORD) {
2337 defaultDetected = true;
2338 }
2339 }
2340
2341 public boolean isEnumDetected() {
2342 return enumDetected;
2343 }
2344
2345 public boolean isDefaultDetected() {
2346 return defaultDetected;
2347 }
2348 }
2349
2350 enum AnnotationParsingMode {
2351 FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true, false),
2352 FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true, false),
2353 ONLY_ESCAPED_REGULAR_ANNOTATIONS(false, false, false),
2354 ALLOW_UNESCAPED_REGULAR_ANNOTATIONS(true, false, false),
2355 ALLOW_UNESCAPED_REGULAR_ANNOTATIONS_AT_MEMBER_MODIFIER_LIST(true, false, true),
2356 PRIMARY_CONSTRUCTOR_MODIFIER_LIST(true, false, false),
2357 PRIMARY_CONSTRUCTOR_MODIFIER_LIST_LOCAL(false, false, false);
2358
2359 boolean allowShortAnnotations;
2360 boolean isFileAnnotationParsingMode;
2361 boolean atMemberStart;
2362
2363 AnnotationParsingMode(
2364 boolean allowShortAnnotations,
2365 boolean isFileAnnotationParsingMode,
2366 boolean atMemberStart
2367 ) {
2368 this.allowShortAnnotations = allowShortAnnotations;
2369 this.isFileAnnotationParsingMode = isFileAnnotationParsingMode;
2370 this.atMemberStart = atMemberStart;
2371 }
2372 }
2373 }