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