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