Parsing dynamic types

This commit is contained in:
Andrey Breslav
2014-11-05 09:52:27 +02:00
parent 0f26998b19
commit 28b466d069
18 changed files with 343 additions and 5 deletions
@@ -67,6 +67,7 @@ public interface JetNodeTypes {
IElementType TYPE_REFERENCE = JetStubElementTypes.TYPE_REFERENCE;
IElementType USER_TYPE = JetStubElementTypes.USER_TYPE;
IElementType DYNAMIC_TYPE = JetStubElementTypes.DYNAMIC_TYPE;
IElementType FUNCTION_TYPE = JetStubElementTypes.FUNCTION_TYPE;
IElementType FUNCTION_TYPE_RECEIVER = JetStubElementTypes.FUNCTION_TYPE_RECEIVER;
JetNodeType SELF_TYPE = new JetNodeType("SELF_TYPE", JetSelfType.class);
@@ -53,7 +53,7 @@ public class JetParsing extends AbstractJetParsing {
private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR);
private static final TokenSet PACKAGE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON);
private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON);
/*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, CAPITALIZED_THIS_KEYWORD, HASH);
/*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, CAPITALIZED_THIS_KEYWORD, HASH, DYNAMIC_KEYWORD);
private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS);
private static final TokenSet VALUE_PARAMETER_FIRST =
TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD), MODIFIER_KEYWORDS);
@@ -1501,6 +1501,7 @@ public class JetParsing extends AbstractJetParsing {
* : userType
* : tupleType
* : nullableType
* : "dynamic"
* ;
*
* nullableType
@@ -1525,7 +1526,13 @@ public class JetParsing extends AbstractJetParsing {
PsiBuilder.Marker typeRefMarker = mark();
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
IElementType lookahead = lookahead(1);
if (at(IDENTIFIER) && lookahead(1) != DOT && lookahead != LT && lookahead != LPAR && at(DYNAMIC_KEYWORD)) {
PsiBuilder.Marker dynamicType = mark();
advance(); // DYNAMIC_KEYWORD
dynamicType.done(DYNAMIC_TYPE);
}
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
parseUserType();
}
else if (at(HASH)) {
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
import java.util.Collections;
import java.util.List;
public class JetDynamicType extends JetElementImplStub<KotlinPlaceHolderStub<JetDynamicType>> implements JetTypeElement {
public JetDynamicType(@NotNull ASTNode node) {
super(node);
}
public JetDynamicType(@NotNull KotlinPlaceHolderStub<JetDynamicType> stub) {
super(stub, JetStubElementTypes.DYNAMIC_TYPE);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitDynamicType(this, data);
}
@NotNull
@Override
public List<JetTypeReference> getTypeArgumentsAsTypes() {
return Collections.emptyList();
}
}
@@ -338,6 +338,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
return visitTypeElement(type, data);
}
public R visitDynamicType(@NotNull JetDynamicType type, D data) {
return visitTypeElement(type, data);
}
public R visitFunctionType(@NotNull JetFunctionType type, D data) {
return visitTypeElement(type, data);
}
@@ -329,6 +329,10 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
super.visitUserType(type, null);
}
public void visitDynamicType(@NotNull JetDynamicType type) {
super.visitDynamicType(type, null);
}
public void visitFunctionType(@NotNull JetFunctionType type) {
super.visitFunctionType(type, null);
}
@@ -872,6 +876,12 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
return null;
}
@Override
public Void visitDynamicType(@NotNull JetDynamicType type, Void data) {
visitDynamicType(type);
return null;
}
@Override
public final Void visitFunctionType(@NotNull JetFunctionType type, Void data) {
visitFunctionType(type);
@@ -330,6 +330,10 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
super.visitUserType(type, data);
}
public void visitDynamicTypeVoid(@NotNull JetDynamicType type, P data) {
super.visitDynamicType(type, data);
}
public void visitFunctionTypeVoid(@NotNull JetFunctionType type, P data) {
super.visitFunctionType(type, data);
}
@@ -869,6 +873,12 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
return null;
}
@Override
public Void visitDynamicType(@NotNull JetDynamicType type, P data) {
visitDynamicTypeVoid(type, data);
return null;
}
@Override
public final Void visitFunctionType(@NotNull JetFunctionType type, P data) {
visitFunctionTypeVoid(type, data);
@@ -78,6 +78,8 @@ public interface JetStubElementTypes {
new JetPlaceHolderStubElementType<JetTypeReference>("TYPE_REFERENCE", JetTypeReference.class);
JetUserTypeElementType USER_TYPE = new JetUserTypeElementType("USER_TYPE");
JetPlaceHolderStubElementType<JetDynamicType> DYNAMIC_TYPE =
new JetPlaceHolderStubElementType<JetDynamicType>("DYNAMIC_TYPE", JetDynamicType.class);
JetPlaceHolderStubElementType<JetFunctionType> FUNCTION_TYPE =
new JetPlaceHolderStubElementType<JetFunctionType>("FUNCTION_TYPE", JetFunctionType.class);
@@ -115,7 +117,7 @@ public interface JetStubElementTypes {
TokenSet DELEGATION_SPECIFIER_TYPES = TokenSet.create(DELEGATOR_BY, DELEGATOR_SUPER_CALL, DELEGATOR_SUPER_CLASS, THIS_CALL);
TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE);
TokenSet TYPE_ELEMENT_TYPES = TokenSet.create(USER_TYPE, NULLABLE_TYPE, FUNCTION_TYPE, DYNAMIC_TYPE);
TokenSet INSIDE_DIRECTIVE_EXPRESSIONS = TokenSet.create(REFERENCE_EXPRESSION, DOT_QUALIFIED_EXPRESSION);
}
@@ -151,6 +151,7 @@ public interface JetTokens {
JetModifierKeywordToken OUT_KEYWORD = JetModifierKeywordToken.softKeywordModifier("out");
JetModifierKeywordToken VARARG_KEYWORD = JetModifierKeywordToken.softKeywordModifier("vararg");
JetModifierKeywordToken REIFIED_KEYWORD = JetModifierKeywordToken.softKeywordModifier("reified");
JetModifierKeywordToken DYNAMIC_KEYWORD = JetModifierKeywordToken.softKeywordModifier("dynamic");
JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally");
JetModifierKeywordToken FINAL_KEYWORD = JetModifierKeywordToken.softKeywordModifier("final");
@@ -167,7 +168,8 @@ public interface JetTokens {
TokenSet SOFT_KEYWORDS = TokenSet.create(FILE_KEYWORD, IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD,
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD,
DYNAMIC_KEYWORD
);
/*
@@ -0,0 +1,5 @@
dynamic class dynamic<dynamic>(dynamic: dynamic) : dynamic {
[dynamic] fun dynamic() {
val dynamic = 1
}
}
@@ -0,0 +1,77 @@
JetFile: DynamicSoftKeyword.kt
PACKAGE_DIRECTIVE
<empty list>
CLASS
MODIFIER_LIST
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dynamic')
PsiWhiteSpace(' ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('dynamic')
TYPE_PARAMETER_LIST
PsiElement(LT)('<')
TYPE_PARAMETER
PsiElement(IDENTIFIER)('dynamic')
PsiElement(GT)('>')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('dynamic')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATOR_SUPER_CLASS
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
FUN
MODIFIER_LIST
ANNOTATION
PsiElement(LBRACKET)('[')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dynamic')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('dynamic')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('dynamic')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+10
View File
@@ -0,0 +1,10 @@
fun foo(
p1: dynamic,
p2: [a] dynamic,
p3: foo.dynamic,
p4: dynamic.foo,
p5: dynamic<T>,
p6: Foo<dynamic>,
p7: dynamic?,
p8: (dynamic) -> dynamic
): dynamic
+138
View File
@@ -0,0 +1,138 @@
JetFile: DynamicTypes.kt
PACKAGE_DIRECTIVE
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p1')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p2')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ANNOTATION
PsiElement(LBRACKET)('[')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p3')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dynamic')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p4')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dynamic')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p5')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('dynamic')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p6')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(GT)('>')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p7')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
NULLABLE_TYPE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(QUEST)('?')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('p8')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(ARROW)('->')
PsiWhiteSpace(' ')
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
PsiWhiteSpace('\n')
PsiElement(RPAR)(')')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
DYNAMIC_TYPE
PsiElement(dynamic)('dynamic')
@@ -166,6 +166,18 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest(fileName);
}
@TestMetadata("DynamicSoftKeyword.kt")
public void testDynamicSoftKeyword() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/DynamicSoftKeyword.kt");
doParsingTest(fileName);
}
@TestMetadata("DynamicTypes.kt")
public void testDynamicTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/DynamicTypes.kt");
doParsingTest(fileName);
}
@TestMetadata("EOLsInComments.kt")
public void testEOLsInComments() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/EOLsInComments.kt");
+1
View File
@@ -23,6 +23,7 @@ typeDescriptor
: functionType
: userType
: nullableType
: "dynamic"
;
nullableType
@@ -4,4 +4,5 @@ fun foo() {
/*TODO: Is 'package' type qualifier syntax correct?*/
// EXIST: package
// NUMBER: 1
// EXIST: dynamic
// NUMBER: 2
+5
View File
@@ -0,0 +1,5 @@
PsiJetFileStubImpl[package=]
PACKAGE_DIRECTIVE:
PROPERTY:[fqName=foo, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReceiverTypeRef=false, hasReturnTypeRef=true, isProbablyNothingType=false, isTopLevel=true, isVar=false, name=foo]
TYPE_REFERENCE:
DYNAMIC_TYPE:
+1
View File
@@ -0,0 +1 @@
val foo: dynamic
@@ -84,6 +84,12 @@ public class StubBuilderTestGenerated extends AbstractStubBuilderTest {
doTest(fileName);
}
@TestMetadata("DynamicType.kt")
public void testDynamicType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/stubs/DynamicType.kt");
doTest(fileName);
}
@TestMetadata("FilePackage.kt")
public void testFilePackage() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/stubs/FilePackage.kt");