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