Generic Java classes supported
This commit is contained in:
@@ -48,11 +48,11 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
|
||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
Collection<? extends JetType> supertypes = delegationSpecifiers.isEmpty()
|
||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers);
|
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers);
|
||||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
||||||
WritableScope members = resolveMembers(classDescriptor, classElement, typeParameters, scope, parameterScope, superclasses);
|
WritableScope members = resolveMembers(classDescriptor, classElement, typeParameters, scope, parameterScope, supertypes);
|
||||||
|
|
||||||
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
for (JetConstructor constructor : classElement.getSecondaryConstructors()) {
|
for (JetConstructor constructor : classElement.getSecondaryConstructors()) {
|
||||||
@@ -65,7 +65,7 @@ public class ClassDescriptorResolver {
|
|||||||
return classDescriptor.initialize(
|
return classDescriptor.initialize(
|
||||||
!open,
|
!open,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
superclasses,
|
supertypes,
|
||||||
members,
|
members,
|
||||||
constructors
|
constructors
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,15 +12,28 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
|
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor {
|
||||||
private final WritableScope classHeaderScope;
|
private final WritableScope classHeaderScope;
|
||||||
private final WritableScope unsubstitutedMemberScope;
|
private final WritableScope writableMemberScope;
|
||||||
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
|
|
||||||
private TypeConstructor typeConstructor;
|
private TypeConstructor typeConstructor;
|
||||||
|
private JetScope unsubstitutedMemberScope;
|
||||||
|
|
||||||
public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
|
public MutableClassDescriptor(@NotNull JetSemanticServices semanticServices, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
|
||||||
super(containingDeclaration);
|
super(containingDeclaration);
|
||||||
this.classHeaderScope = semanticServices.createWritableScope(outerScope, this);
|
this.classHeaderScope = semanticServices.createWritableScope(outerScope, this);
|
||||||
this.unsubstitutedMemberScope = semanticServices.createWritableScope(classHeaderScope, this);
|
this.writableMemberScope = semanticServices.createWritableScope(classHeaderScope, this);
|
||||||
|
this.unsubstitutedMemberScope = this.writableMemberScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration) {
|
||||||
|
super(containingDeclaration);
|
||||||
|
this.classHeaderScope = null;
|
||||||
|
this.writableMemberScope = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnsubstitutedMemberScope(@NotNull JetScope unsubstitutedMemberScope) {
|
||||||
|
assert writableMemberScope == null;
|
||||||
|
this.unsubstitutedMemberScope = unsubstitutedMemberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -66,8 +79,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public WritableScope getUnsubstitutedMemberScope() {
|
public WritableScope getWritableUnsubstitutedMemberScope() {
|
||||||
return unsubstitutedMemberScope;
|
return writableMemberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public class TopDownAnalyzer {
|
|||||||
classes.put(klass, mutableClassDescriptor);
|
classes.put(klass, mutableClassDescriptor);
|
||||||
declaringScopes.put(klass, declaringScope);
|
declaringScopes.put(klass, declaringScope);
|
||||||
|
|
||||||
return mutableClassDescriptor.getUnsubstitutedMemberScope();
|
return mutableClassDescriptor.getWritableUnsubstitutedMemberScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processExtension(JetExtension extension) {
|
private void processExtension(JetExtension extension) {
|
||||||
@@ -178,7 +178,7 @@ public class TopDownAnalyzer {
|
|||||||
public void visitClass(JetClass klass) {
|
public void visitClass(JetClass klass) {
|
||||||
MutableClassDescriptor mutableClassDescriptor = classes.get(klass);
|
MutableClassDescriptor mutableClassDescriptor = classes.get(klass);
|
||||||
processPrimaryConstructor(mutableClassDescriptor, klass);
|
processPrimaryConstructor(mutableClassDescriptor, klass);
|
||||||
processBehaviorDeclarators(mutableClassDescriptor.getUnsubstitutedMemberScope(), klass.getDeclarations());
|
processBehaviorDeclarators(mutableClassDescriptor.getWritableUnsubstitutedMemberScope(), klass.getDeclarations());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -225,7 +225,7 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
|
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
|
||||||
// TODO : not all the parameters are real properties
|
// TODO : not all the parameters are real properties
|
||||||
WritableScope memberScope = classDescriptor.getUnsubstitutedMemberScope(); // TODO : this is REALLY questionable
|
WritableScope memberScope = classDescriptor.getWritableUnsubstitutedMemberScope(); // TODO : this is REALLY questionable
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(memberScope, classDescriptor, klass);
|
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(memberScope, classDescriptor, klass);
|
||||||
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
||||||
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
||||||
@@ -242,10 +242,10 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, constructor, false);
|
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getWritableUnsubstitutedMemberScope(), classDescriptor, constructor, false);
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classDescriptor.addConstructor(constructorDescriptor);
|
||||||
functions.put(constructor, constructorDescriptor);
|
functions.put(constructor, constructorDescriptor);
|
||||||
declaringScopes.put(constructor, classDescriptor.getUnsubstitutedMemberScope());
|
declaringScopes.put(constructor, classDescriptor.getWritableUnsubstitutedMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) {
|
private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) {
|
||||||
@@ -359,7 +359,22 @@ public class TopDownAnalyzer {
|
|||||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(declaration, initializer);
|
JetFlowInformationProvider flowInformationProvider = computeFlowData(declaration, initializer);
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
||||||
JetType type = typeInferrer.getType(declaringScope, initializer, false);
|
JetType type = typeInferrer.getType(declaringScope, initializer, false);
|
||||||
// TODO : check type
|
|
||||||
|
JetType expectedType;
|
||||||
|
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||||
|
if (setter != null) {
|
||||||
|
expectedType = setter.getUnsubstitutedReturnType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expectedType = propertyDescriptor.getInType();
|
||||||
|
if (expectedType == null) {
|
||||||
|
expectedType = propertyDescriptor.getOutType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type != null && expectedType != null
|
||||||
|
&& !semanticServices.getTypeChecker().isConvertibleTo(type, expectedType)) {
|
||||||
|
semanticServices.getErrorHandler().typeMismatch(initializer, expectedType, type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingTraceAdapter fieldAccessTrackingTrace = new BindingTraceAdapter(trace) {
|
BindingTraceAdapter fieldAccessTrackingTrace = new BindingTraceAdapter(trace) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class TypeResolver {
|
|||||||
result[0] = new JetTypeImpl(
|
result[0] = new JetTypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
typeParameterDescriptor.getTypeConstructor(),
|
typeParameterDescriptor.getTypeConstructor(),
|
||||||
nullable || hasNullableBound(typeParameterDescriptor),
|
nullable || TypeUtils.hasNullableBound(typeParameterDescriptor),
|
||||||
Collections.<TypeProjection>emptyList(),
|
Collections.<TypeProjection>emptyList(),
|
||||||
// TODO : joint domain
|
// TODO : joint domain
|
||||||
JetStandardClasses.STUB
|
JetStandardClasses.STUB
|
||||||
@@ -70,22 +70,33 @@ public class TypeResolver {
|
|||||||
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
||||||
int expectedArgumentCount = typeConstructor.getParameters().size();
|
int expectedArgumentCount = typeConstructor.getParameters().size();
|
||||||
int actualArgumentCount = arguments.size();
|
int actualArgumentCount = arguments.size();
|
||||||
if (actualArgumentCount != expectedArgumentCount) {
|
if (ErrorUtils.isError(typeConstructor)) {
|
||||||
String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
|
|
||||||
if (actualArgumentCount == 0) {
|
|
||||||
semanticServices.getErrorHandler().genericError(type.getNode(), errorMessage);
|
|
||||||
} else if (expectedArgumentCount == 0) {
|
|
||||||
semanticServices.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result[0] = new JetTypeImpl(
|
result[0] = new JetTypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
typeConstructor,
|
typeConstructor,
|
||||||
nullable,
|
nullable,
|
||||||
arguments,
|
arguments, // TODO : review
|
||||||
classDescriptor.getMemberScope(arguments)
|
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (actualArgumentCount != expectedArgumentCount) {
|
||||||
|
String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
|
||||||
|
if (actualArgumentCount == 0) {
|
||||||
|
semanticServices.getErrorHandler().genericError(type.getNode(), errorMessage);
|
||||||
|
} else if (expectedArgumentCount == 0) {
|
||||||
|
semanticServices.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result[0] = new JetTypeImpl(
|
||||||
|
attributes,
|
||||||
|
typeConstructor,
|
||||||
|
nullable,
|
||||||
|
arguments,
|
||||||
|
classDescriptor.getMemberScope(arguments)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,15 +139,6 @@ public class TypeResolver {
|
|||||||
return result[0];
|
return result[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNullableBound(TypeParameterDescriptor typeParameterDescriptor) {
|
|
||||||
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
|
||||||
if (bound.isNullable()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<JetType> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) {
|
private List<JetType> resolveTypes(JetScope scope, List<JetTypeReference> argumentElements) {
|
||||||
final List<JetType> arguments = new ArrayList<JetType>();
|
final List<JetType> arguments = new ArrayList<JetType>();
|
||||||
for (JetTypeReference argumentElement : argumentElements) {
|
for (JetTypeReference argumentElement : argumentElements) {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
JetType type = semanticServices.getTypeTransformer().transform(field.getType());
|
JetType type = semanticServices.getTypeTransformer().transformToType(field.getType());
|
||||||
boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
|
boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
@@ -97,7 +97,7 @@ public class JavaClassMembersScope implements JetScope {
|
|||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
||||||
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptor, parameters),
|
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptor, parameters),
|
||||||
semanticServices.getTypeTransformer().transform(method.getReturnType())
|
semanticServices.getTypeTransformer().transformToType(method.getReturnType())
|
||||||
);
|
);
|
||||||
semanticServices.getTrace().recordDeclarationResolution(method, functionDescriptor);
|
semanticServices.getTrace().recordDeclarationResolution(method, functionDescriptor);
|
||||||
writableFunctionGroup.addFunction(functionDescriptor);
|
writableFunctionGroup.addFunction(functionDescriptor);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java;
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.resolve.MutableClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.WritableFunctionGroup;
|
import org.jetbrains.jet.lang.resolve.WritableFunctionGroup;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
@@ -31,6 +33,7 @@ public class JavaDescriptorResolver {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>();
|
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>();
|
||||||
|
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
|
||||||
protected final Map<String, NamespaceDescriptor> namespaceDescriptorCache = new HashMap<String, NamespaceDescriptor>();
|
protected final Map<String, NamespaceDescriptor> namespaceDescriptorCache = new HashMap<String, NamespaceDescriptor>();
|
||||||
protected final JavaPsiFacade javaFacade;
|
protected final JavaPsiFacade javaFacade;
|
||||||
protected final GlobalSearchScope javaSearchScope;
|
protected final GlobalSearchScope javaSearchScope;
|
||||||
@@ -67,25 +70,32 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ClassDescriptor createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
|
private ClassDescriptor createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
|
||||||
|
assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
|
||||||
|
classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO
|
||||||
|
|
||||||
String name = psiClass.getName();
|
String name = psiClass.getName();
|
||||||
PsiModifierList modifierList = psiClass.getModifierList();
|
PsiModifierList modifierList = psiClass.getModifierList();
|
||||||
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
MutableClassDescriptor classDescriptor = new MutableClassDescriptor(
|
||||||
JAVA_ROOT,
|
JAVA_ROOT
|
||||||
Collections.<Attribute>emptyList(), // TODO
|
|
||||||
name
|
|
||||||
);
|
);
|
||||||
|
classDescriptor.setName(name);
|
||||||
|
|
||||||
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
classDescriptor.initialize(
|
List<JetType> supertypes = new ArrayList<JetType>();
|
||||||
|
classDescriptor.setTypeConstructor(new TypeConstructorImpl(
|
||||||
|
classDescriptor,
|
||||||
|
Collections.<Attribute>emptyList(), // TODO
|
||||||
// TODO
|
// TODO
|
||||||
modifierList == null ? false : modifierList.hasModifierProperty(PsiModifier.FINAL),
|
modifierList == null ? false : modifierList.hasModifierProperty(PsiModifier.FINAL),
|
||||||
|
name,
|
||||||
resolveTypeParameters(psiClass, classDescriptor),
|
resolveTypeParameters(psiClass, classDescriptor),
|
||||||
getSupertypes(psiClass),
|
supertypes
|
||||||
new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false),
|
|
||||||
constructors
|
|
||||||
);
|
|
||||||
|
|
||||||
|
));
|
||||||
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
||||||
|
// UGLY HACK
|
||||||
|
supertypes.addAll(getSupertypes(psiClass));
|
||||||
|
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
|
||||||
|
|
||||||
// NOTE: this writes into constructors after it is remembered by the classDescriptor
|
// NOTE: this writes into constructors after it is remembered by the classDescriptor
|
||||||
PsiMethod[] psiConstructors = psiClass.getConstructors();
|
PsiMethod[] psiConstructors = psiClass.getConstructors();
|
||||||
@@ -95,7 +105,7 @@ public class JavaDescriptorResolver {
|
|||||||
Collections.<Attribute>emptyList(), // TODO
|
Collections.<Attribute>emptyList(), // TODO
|
||||||
false);
|
false);
|
||||||
constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()));
|
constructorDescriptor.initialize(resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()));
|
||||||
constructors.addFunction(constructorDescriptor);
|
classDescriptor.addConstructor(constructorDescriptor);
|
||||||
semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor);
|
semanticServices.getTrace().recordDeclarationResolution(constructor, constructorDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,40 +114,54 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeParameterDescriptor> resolveTypeParameters(@NotNull PsiClass psiClass, @NotNull ClassDescriptor classDescriptor) {
|
private List<TypeParameterDescriptor> resolveTypeParameters(@NotNull PsiClass psiClass, @NotNull ClassDescriptor classDescriptor) {
|
||||||
if (1 < 2) return Collections.emptyList(); // TODO
|
|
||||||
List<TypeParameterDescriptor> result = Lists.newArrayList();
|
List<TypeParameterDescriptor> result = Lists.newArrayList();
|
||||||
PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||||
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
|
TypeParameterDescriptor typeParameterDescriptor = resolveTypeParameter(typeParameter);
|
||||||
Set<JetType> upperBounds;
|
result.add(typeParameterDescriptor);
|
||||||
JetType boundsAsType;
|
|
||||||
if (referencedTypes.length == 0){
|
|
||||||
boundsAsType = JetStandardClasses.getNullableAnyType();
|
|
||||||
upperBounds = Collections.singleton(boundsAsType);
|
|
||||||
}
|
|
||||||
else if (referencedTypes.length == 1) {
|
|
||||||
boundsAsType = semanticServices.getTypeTransformer().transform(referencedTypes[0]);
|
|
||||||
upperBounds = Collections.singleton(boundsAsType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
upperBounds = Sets.newLinkedHashSet();
|
|
||||||
for (PsiClassType referencedType : referencedTypes) {
|
|
||||||
upperBounds.add(semanticServices.getTypeTransformer().transform(referencedType));
|
|
||||||
}
|
|
||||||
boundsAsType = TypeUtils.safeIntersect(semanticServices.getTypeChecker(), upperBounds);
|
|
||||||
}
|
|
||||||
result.add(new TypeParameterDescriptor(
|
|
||||||
classDescriptor,
|
|
||||||
Collections.<Attribute>emptyList(), // TODO
|
|
||||||
Variance.INVARIANT,
|
|
||||||
typeParameter.getName(),
|
|
||||||
upperBounds,
|
|
||||||
boundsAsType
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeParameterDescriptor createJavaTypeParameterDescriptor(@NotNull DeclarationDescriptor owner, @NotNull PsiTypeParameter typeParameter) {
|
||||||
|
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
|
||||||
|
Set<JetType> upperBounds;
|
||||||
|
JetType boundsAsType;
|
||||||
|
if (referencedTypes.length == 0){
|
||||||
|
boundsAsType = JetStandardClasses.getNullableAnyType();
|
||||||
|
upperBounds = Collections.singleton(boundsAsType);
|
||||||
|
}
|
||||||
|
else if (referencedTypes.length == 1) {
|
||||||
|
boundsAsType = semanticServices.getTypeTransformer().transformToType(referencedTypes[0]);
|
||||||
|
upperBounds = Collections.singleton(boundsAsType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
upperBounds = Sets.newLinkedHashSet();
|
||||||
|
for (PsiClassType referencedType : referencedTypes) {
|
||||||
|
upperBounds.add(semanticServices.getTypeTransformer().transformToType(referencedType));
|
||||||
|
}
|
||||||
|
boundsAsType = TypeUtils.safeIntersect(semanticServices.getJetSemanticServices().getTypeChecker(), upperBounds);
|
||||||
|
}
|
||||||
|
return new TypeParameterDescriptor(
|
||||||
|
owner,
|
||||||
|
Collections.<Attribute>emptyList(), // TODO
|
||||||
|
Variance.INVARIANT,
|
||||||
|
typeParameter.getName(),
|
||||||
|
upperBounds,
|
||||||
|
boundsAsType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public TypeParameterDescriptor resolveTypeParameter(@NotNull PsiTypeParameter psiTypeParameter) {
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
|
||||||
|
if (typeParameterDescriptor == null) {
|
||||||
|
typeParameterDescriptor = createJavaTypeParameterDescriptor(JAVA_ROOT, psiTypeParameter);
|
||||||
|
typeParameterDescriptorCache.put(psiTypeParameter, typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
return typeParameterDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
private Collection<? extends JetType> getSupertypes(PsiClass psiClass) {
|
private Collection<? extends JetType> getSupertypes(PsiClass psiClass) {
|
||||||
List<JetType> result = new ArrayList<JetType>();
|
List<JetType> result = new ArrayList<JetType>();
|
||||||
result.add(JetStandardClasses.getAnyType());
|
result.add(JetStandardClasses.getAnyType());
|
||||||
@@ -148,7 +172,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes) {
|
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes) {
|
||||||
for (PsiClassType type : extendsListTypes) {
|
for (PsiClassType type : extendsListTypes) {
|
||||||
JetType transform = semanticServices.getTypeTransformer().transform(type);
|
JetType transform = semanticServices.getTypeTransformer().transformToType(type);
|
||||||
|
|
||||||
result.add(TypeUtils.makeNotNullable(transform));
|
result.add(TypeUtils.makeNotNullable(transform));
|
||||||
}
|
}
|
||||||
@@ -207,7 +231,7 @@ public class JavaDescriptorResolver {
|
|||||||
Collections.<Attribute>emptyList(), // TODO
|
Collections.<Attribute>emptyList(), // TODO
|
||||||
name == null ? "p" + i : name,
|
name == null ? "p" + i : name,
|
||||||
null, // TODO : review
|
null, // TODO : review
|
||||||
semanticServices.getTypeTransformer().transform(parameter.getType()),
|
semanticServices.getTypeTransformer().transformToType(parameter.getType()),
|
||||||
false,
|
false,
|
||||||
parameter.isVarArgs()
|
parameter.isVarArgs()
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.intellij.openapi.project.Project;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.types.BindingTrace;
|
import org.jetbrains.jet.lang.types.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -13,13 +12,13 @@ public class JavaSemanticServices {
|
|||||||
private final JavaTypeTransformer typeTransformer;
|
private final JavaTypeTransformer typeTransformer;
|
||||||
private final JavaDescriptorResolver descriptorResolver;
|
private final JavaDescriptorResolver descriptorResolver;
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
private final JetTypeChecker typeChecker;
|
private final JetSemanticServices jetSemanticServices;
|
||||||
|
|
||||||
public JavaSemanticServices(Project project, JetSemanticServices jetSemanticServices, BindingTrace trace) {
|
public JavaSemanticServices(Project project, JetSemanticServices jetSemanticServices, BindingTrace trace) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
this.descriptorResolver = new JavaDescriptorResolver(project, this);
|
this.descriptorResolver = new JavaDescriptorResolver(project, this);
|
||||||
this.typeTransformer = new JavaTypeTransformer(jetSemanticServices.getStandardLibrary(), descriptorResolver);
|
this.typeTransformer = new JavaTypeTransformer(jetSemanticServices.getStandardLibrary(), descriptorResolver);
|
||||||
this.typeChecker = new JetTypeChecker(jetSemanticServices.getStandardLibrary());
|
this.jetSemanticServices = jetSemanticServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -37,8 +36,7 @@ public class JavaSemanticServices {
|
|||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
public JetSemanticServices getJetSemanticServices() {
|
||||||
public JetTypeChecker getTypeChecker() {
|
return jetSemanticServices;
|
||||||
return typeChecker;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,36 @@ public class JavaTypeTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType transform(PsiType javaType) {
|
public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType, @NotNull final TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
TypeProjection result = javaType.accept(new PsiTypeVisitor<TypeProjection>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeProjection visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeProjection visitWildcardType(PsiWildcardType wildcardType) {
|
||||||
|
if (!wildcardType.isBounded()) {
|
||||||
|
return TypeUtils.makeStarProjection(typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
Variance variance = wildcardType.isExtends() ? Variance.OUT_VARIANCE : Variance.IN_VARIANCE;
|
||||||
|
|
||||||
|
PsiType bound = wildcardType.getBound();
|
||||||
|
assert bound != null;
|
||||||
|
return new TypeProjection(variance, transformToType(bound));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeProjection visitType(PsiType type) {
|
||||||
|
return new TypeProjection(transformToType(type));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetType transformToType(@NotNull PsiType javaType) {
|
||||||
return javaType.accept(new PsiTypeVisitor<JetType>() {
|
return javaType.accept(new PsiTypeVisitor<JetType>() {
|
||||||
@Override
|
@Override
|
||||||
public JetType visitClassType(PsiClassType classType) {
|
public JetType visitClassType(PsiClassType classType) {
|
||||||
@@ -36,31 +65,46 @@ public class JavaTypeTransformer {
|
|||||||
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
||||||
}
|
}
|
||||||
|
|
||||||
JetType jetAnalog = getClassTypesMap().get(psiClass.getQualifiedName());
|
if (psiClass instanceof PsiTypeParameter) {
|
||||||
if (jetAnalog != null) {
|
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
|
||||||
return jetAnalog;
|
TypeParameterDescriptor typeParameterDescriptor = resolver.resolveTypeParameter(typeParameter);
|
||||||
}
|
return new JetTypeImpl(
|
||||||
|
Collections.<Attribute>emptyList(),
|
||||||
|
typeParameterDescriptor.getTypeConstructor(),
|
||||||
|
!TypeUtils.hasNullableBound(typeParameterDescriptor),
|
||||||
|
Collections.<TypeProjection>emptyList(),
|
||||||
|
typeParameterDescriptor.getBoundsAsType().getMemberScope());
|
||||||
|
|
||||||
ClassDescriptor descriptor = resolver.resolveClass(psiClass);
|
|
||||||
|
|
||||||
List<TypeProjection> arguments = Lists.newArrayList();
|
|
||||||
if (classType.isRaw()) { // TODO
|
|
||||||
// List<TypeParameterDescriptor> parameters = descriptor.getTypeConstructor().getParameters();
|
|
||||||
// for (TypeParameterDescriptor parameter : parameters) {
|
|
||||||
// arguments.add(TypeUtils.makeStarProjection(parameter));
|
|
||||||
// }
|
|
||||||
} else { // TODO
|
|
||||||
// PsiType[] psiArguments = classType.getParameters();
|
|
||||||
// for (PsiType psiArgument : psiArguments) {
|
|
||||||
// arguments.add(new TypeProjection(transform(psiArgument)));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return new JetTypeImpl(
|
else {
|
||||||
Collections.<Attribute>emptyList(),
|
JetType jetAnalog = getClassTypesMap().get(psiClass.getQualifiedName());
|
||||||
descriptor.getTypeConstructor(),
|
if (jetAnalog != null) {
|
||||||
true,
|
return jetAnalog;
|
||||||
arguments,
|
}
|
||||||
descriptor.getMemberScope(arguments));
|
|
||||||
|
ClassDescriptor descriptor = resolver.resolveClass(psiClass);
|
||||||
|
|
||||||
|
List<TypeProjection> arguments = Lists.newArrayList();
|
||||||
|
if (classType.isRaw()) {
|
||||||
|
List<TypeParameterDescriptor> parameters = descriptor.getTypeConstructor().getParameters();
|
||||||
|
for (TypeParameterDescriptor parameter : parameters) {
|
||||||
|
arguments.add(TypeUtils.makeStarProjection(parameter));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PsiType[] psiArguments = classType.getParameters();
|
||||||
|
for (int i = 0, psiArgumentsLength = psiArguments.length; i < psiArgumentsLength; i++) {
|
||||||
|
PsiType psiArgument = psiArguments[i];
|
||||||
|
TypeParameterDescriptor typeParameterDescriptor = descriptor.getTypeConstructor().getParameters().get(i);
|
||||||
|
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new JetTypeImpl(
|
||||||
|
Collections.<Attribute>emptyList(),
|
||||||
|
descriptor.getTypeConstructor(),
|
||||||
|
true,
|
||||||
|
arguments,
|
||||||
|
descriptor.getMemberScope(arguments));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -73,16 +117,10 @@ public class JavaTypeTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetType visitArrayType(PsiArrayType arrayType) {
|
public JetType visitArrayType(PsiArrayType arrayType) {
|
||||||
JetType type = transform(arrayType.getComponentType());
|
JetType type = transformToType(arrayType.getComponentType());
|
||||||
return TypeUtils.makeNullable(standardLibrary.getArrayType(type));
|
return TypeUtils.makeNullable(standardLibrary.getArrayType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetType visitWildcardType(PsiWildcardType wildcardType) {
|
|
||||||
System.out.println("!!!");
|
|
||||||
return JetStandardClasses.getNullableAnyType(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetType visitType(PsiType type) {
|
public JetType visitType(PsiType type) {
|
||||||
throw new UnsupportedOperationException("Unsupported type: " + type.getPresentableText()); // TODO
|
throw new UnsupportedOperationException("Unsupported type: " + type.getPresentableText()); // TODO
|
||||||
|
|||||||
@@ -149,6 +149,10 @@ public class ErrorUtils {
|
|||||||
return ERROR_CLASS;
|
return ERROR_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isError(@NotNull TypeConstructor typeConstructor) {
|
||||||
|
return typeConstructor == ERROR_CLASS.getTypeConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
private static class ErrorTypeImpl implements JetType {
|
private static class ErrorTypeImpl implements JetType {
|
||||||
|
|
||||||
private final TypeConstructor constructor;
|
private final TypeConstructor constructor;
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
|
|||||||
@Override
|
@Override
|
||||||
public JetScope getMemberScope() {
|
public JetScope getMemberScope() {
|
||||||
if (memberScope == null) {
|
if (memberScope == null) {
|
||||||
// TODO
|
// TODO : this was supposed to mean something...
|
||||||
|
throw new IllegalStateException(this.toString());
|
||||||
}
|
}
|
||||||
return memberScope;
|
return memberScope;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,4 +226,13 @@ public class TypeUtils {
|
|||||||
collectAllSupertypes(type, result);
|
collectAllSupertypes(type, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasNullableBound(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
||||||
|
if (bound.isNullable()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.resolve;
|
|||||||
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -91,6 +92,17 @@ public class DescriptorUtil {
|
|||||||
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
|
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
|
||||||
builder.append("class ").append(renderName(descriptor));
|
builder.append("class ").append(renderName(descriptor));
|
||||||
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
|
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
|
||||||
|
Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
||||||
|
if (!supertypes.isEmpty()) {
|
||||||
|
builder.append(" : ");
|
||||||
|
for (Iterator<? extends JetType> iterator = supertypes.iterator(); iterator.hasNext(); ) {
|
||||||
|
JetType supertype = iterator.next();
|
||||||
|
builder.append(supertype);
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
builder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return super.visitClassDescriptor(descriptor, builder);
|
return super.visitClassDescriptor(descriptor, builder);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,6 @@ fun test() {
|
|||||||
for (i in new Range0());
|
for (i in new Range0());
|
||||||
for (i in new Range1());
|
for (i in new Range1());
|
||||||
|
|
||||||
for (i in (new ArrayList() : List));
|
for (i in (new ArrayList<Int>() : List<Int>));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import java.*
|
|||||||
import util.*
|
import util.*
|
||||||
import <error>utils</error>.*
|
import <error>utils</error>.*
|
||||||
|
|
||||||
fun test(l : java.util.List) {
|
val l : List<in Int> = new ArrayList<Int>()
|
||||||
|
|
||||||
|
fun test(l : java.util.List<Int>) {
|
||||||
val x : java.<error>List</error>
|
val x : java.<error>List</error>
|
||||||
val y : java.util.List
|
val y : java.util.List<Int>
|
||||||
val b : java.lang.Object
|
val b : java.lang.Object
|
||||||
val a : util.List
|
val a : util.List<Int>
|
||||||
val z : java.<error>utils</error>.List
|
val z : java.<error>utils</error>.List<Int>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
class Foo : java.util.ArrayList
|
class Foo : java.util.ArrayList<*>
|
||||||
@@ -59,7 +59,7 @@ fun f_plus(): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> tt(t : T) : T {
|
fun <T> tt(t : T) : T {
|
||||||
val x : List = 0
|
val x : List<Int> = 0
|
||||||
x`java::java.util.List.get()`[1]
|
x`java::java.util.List.get()`[1]
|
||||||
val foo = new `Bar()`Bar()
|
val foo = new `Bar()`Bar()
|
||||||
foo`!`[null, 1]
|
foo`!`[null, 1]
|
||||||
|
|||||||
@@ -267,6 +267,10 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
assertSubtype("Derived_outT<Int>", "Base_outT<Any>");
|
assertSubtype("Derived_outT<Int>", "Base_outT<Any>");
|
||||||
assertSubtype("Derived_T<Int>", "Base_T<out Any>");
|
assertSubtype("Derived_T<Int>", "Base_T<out Any>");
|
||||||
assertSubtype("Derived_T<Any>", "Base_T<in Int>");
|
assertSubtype("Derived_T<Any>", "Base_T<in Int>");
|
||||||
|
|
||||||
|
assertSubtype("Derived_T<Int>", "Base_T<in Int>");
|
||||||
|
assertSubtype("MDerived_T<Int>", "Base_T<in Int>");
|
||||||
|
assertSubtype("ArrayList<Int>", "List<in Int>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNullable() throws Exception {
|
public void testNullable() throws Exception {
|
||||||
@@ -438,12 +442,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
assertEquals(expected, allSupertypes);
|
assertEquals(expected, allSupertypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSubtype(String type1, String type2) {
|
private void assertSubtype(String subtype, String supertype) {
|
||||||
assertSubtypingRelation(type1, type2, true);
|
assertSubtypingRelation(subtype, supertype, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNotSubtype(String type1, String type2) {
|
private void assertNotSubtype(String subtype, String supertype) {
|
||||||
assertSubtypingRelation(type1, type2, false);
|
assertSubtypingRelation(subtype, supertype, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertIntersection(String expected, String... types) {
|
private void assertIntersection(String expected, String... types) {
|
||||||
@@ -465,9 +469,9 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
assertTrue(result + " != " + expected, JetTypeImpl.equalTypes(result, makeType(expected)));
|
assertTrue(result + " != " + expected, JetTypeImpl.equalTypes(result, makeType(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
private void assertSubtypingRelation(String subtype, String supertype, boolean expected) {
|
||||||
JetType typeNode1 = makeType(type1);
|
JetType typeNode1 = makeType(subtype);
|
||||||
JetType typeNode2 = makeType(type2);
|
JetType typeNode2 = makeType(supertype);
|
||||||
boolean result = semanticServices.getTypeChecker().isSubtypeOf(
|
boolean result = semanticServices.getTypeChecker().isSubtypeOf(
|
||||||
typeNode1,
|
typeNode1,
|
||||||
typeNode2);
|
typeNode2);
|
||||||
@@ -534,6 +538,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
"open class Derived1_inT<in T> : Base_inT<T>, Derived_T<T>",
|
"open class Derived1_inT<in T> : Base_inT<T>, Derived_T<T>",
|
||||||
"open class Base_outT<out T>",
|
"open class Base_outT<out T>",
|
||||||
"open class Derived_outT<out T> : Base_outT<T>",
|
"open class Derived_outT<out T> : Base_outT<T>",
|
||||||
|
"open class MDerived_T> : Base_outT<out T>, Base_T<T>",
|
||||||
"class Properties { val p : Int }",
|
"class Properties { val p : Int }",
|
||||||
"class Props<T> { val p : T }",
|
"class Props<T> { val p : T }",
|
||||||
"class Functions<T> { " +
|
"class Functions<T> { " +
|
||||||
@@ -547,7 +552,12 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
"fun isValid() : Boolean " +
|
"fun isValid() : Boolean " +
|
||||||
"fun isValid(x : Int) : Boolean " +
|
"fun isValid(x : Int) : Boolean " +
|
||||||
"val p : Boolean " +
|
"val p : Boolean " +
|
||||||
"}"
|
"}",
|
||||||
|
|
||||||
|
"open class List<E>",
|
||||||
|
"open class AbstractList<E> : List<E?>",
|
||||||
|
"open class ArrayList<E> : Any, AbstractList<E?>, List<E?>"
|
||||||
|
|
||||||
};
|
};
|
||||||
private String[] FUNCTION_DECLARATIONS = {
|
private String[] FUNCTION_DECLARATIONS = {
|
||||||
"fun f() : Unit {}",
|
"fun f() : Unit {}",
|
||||||
|
|||||||
Reference in New Issue
Block a user