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