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