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