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