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