Resolve framework refactored
This commit is contained in:
@@ -1,27 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.modules;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.types.ClassDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.ExtensionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.MethodDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.PropertyDescriptor;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public interface MemberDomain {
|
|
||||||
@NotNull
|
|
||||||
Collection<MethodDescriptor> getMethods(String name);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ClassDescriptor getClass(String name);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
PropertyDescriptor getProperty(String name);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ExtensionDescriptor getExtension(String name);
|
|
||||||
}
|
|
||||||
@@ -30,75 +30,44 @@ public class ClassDescriptorResolver {
|
|||||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||||
: resolveTypes(typeParameterScope, delegationSpecifiers);
|
: resolveTypes(typeParameterScope, delegationSpecifiers);
|
||||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
||||||
|
WritableScope members = resolveMembers(classElement, typeParameters, scope, typeParameterScope, superclasses);
|
||||||
|
|
||||||
return new ClassDescriptor(
|
return new ClassDescriptor(
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
||||||
!open,
|
!open,
|
||||||
classElement.getName(),
|
classElement.getName(),
|
||||||
typeParameters,
|
typeParameters,
|
||||||
superclasses,
|
superclasses,
|
||||||
resolveMemberDomain(classElement, scope, typeParameterScope, superclasses)
|
members
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeMemberDomain resolveMemberDomain(
|
private WritableScope resolveMembers(
|
||||||
final JetClass classElement,
|
final JetClass classElement,
|
||||||
|
List<TypeParameterDescriptor> typeParameters,
|
||||||
final JetScope outerScope,
|
final JetScope outerScope,
|
||||||
final TypeParameterExtensibleScope typeParameterScope,
|
final TypeParameterExtensibleScope typeParameterScope,
|
||||||
final Collection<? extends Type> supertypes) {
|
final Collection<? extends Type> supertypes) {
|
||||||
// TODO : Cache!!!
|
|
||||||
return new TypeMemberDomain() {
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(Type contextType, @NotNull String name) {
|
|
||||||
// TODO : primary constructor parameters
|
|
||||||
List<JetDeclaration> declarations = classElement.getDeclarations();
|
|
||||||
for (JetDeclaration declaration : declarations) {
|
|
||||||
if (!name.equals(declaration.getName())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (declaration instanceof JetProperty) {
|
|
||||||
JetProperty property = (JetProperty) declaration;
|
|
||||||
|
|
||||||
if (property.getPropertyTypeRef() != null) {
|
WritableScope memberDeclarations = new WritableScope();
|
||||||
return substituteInPropertyDescriptor(contextType, resolvePropertyDescriptor(typeParameterScope, property));
|
|
||||||
} else {
|
List<JetDeclaration> declarations = classElement.getDeclarations();
|
||||||
// TODO : Caution: a cyclic dependency possible
|
for (JetDeclaration declaration : declarations) {
|
||||||
throw new UnsupportedOperationException();
|
if (declaration instanceof JetProperty) {
|
||||||
}
|
JetProperty property = (JetProperty) declaration;
|
||||||
}
|
|
||||||
|
if (property.getPropertyTypeRef() != null) {
|
||||||
|
memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(typeParameterScope, property));
|
||||||
|
} else {
|
||||||
|
// TODO : Caution: a cyclic dependency possible
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
for (Type supertype : supertypes) {
|
|
||||||
PropertyDescriptor property = supertype.getMemberDomain().getProperty(JetTypeChecker.INSTANCE.substitute(contextType, supertype, Variance.INVARIANT), name);
|
|
||||||
if (property != null) {
|
|
||||||
return property;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private PropertyDescriptor substituteInPropertyDescriptor(Type contextType, PropertyDescriptor propertyDescriptor) {
|
|
||||||
if (contextType.getConstructor().getParameters().isEmpty()) {
|
|
||||||
return propertyDescriptor;
|
|
||||||
}
|
}
|
||||||
return new LazySubstitutedPropertyDescriptorImpl(propertyDescriptor, contextType);
|
|
||||||
|
return memberDeclarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<TypeParameterDescriptor> resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) {
|
private static List<TypeParameterDescriptor> resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) {
|
||||||
|
|||||||
@@ -2,16 +2,31 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
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.modules.MemberDomain;
|
|
||||||
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public interface JetScope extends NamespaceDomain, MemberDomain {
|
public interface JetScope {
|
||||||
JetScope EMPTY = new JetScopeImpl() {};
|
JetScope EMPTY = new JetScopeImpl() {};
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Collection<MethodDescriptor> getMethods(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ClassDescriptor getClass(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
PropertyDescriptor getProperty(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ExtensionDescriptor getExtension(String name);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
NamespaceDescriptor getNamespace(String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
TypeParameterDescriptor getTypeParameterDescriptor(String name);
|
TypeParameterDescriptor getTypeParameterDescriptor(String name);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
|||||||
|
|
||||||
public ScopeWithReceiver(JetScope outerScope, Type receiverType) {
|
public ScopeWithReceiver(JetScope outerScope, Type receiverType) {
|
||||||
this.outerScope = outerScope;
|
this.outerScope = outerScope;
|
||||||
this.receiverTypeScope = new TypeScope(receiverType);
|
this.receiverTypeScope = receiverType.getMemberScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class SubstitutingScope implements JetScope {
|
||||||
|
|
||||||
|
private final JetScope workerScope;
|
||||||
|
private final Map<TypeConstructor, TypeProjection> substitutionContext;
|
||||||
|
|
||||||
|
public SubstitutingScope(JetScope workerScope, Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||||
|
this.workerScope = workerScope;
|
||||||
|
this.substitutionContext = substitutionContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
PropertyDescriptor property = workerScope.getProperty(name);
|
||||||
|
if (property == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new LazySubstitutedPropertyDescriptorImpl(property, substitutionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<MethodDescriptor> getMethods(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Type getThisType() {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,12 +36,13 @@ public class TypeResolver {
|
|||||||
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
ClassDescriptor classDescriptor = resolveClass(scope, type);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
||||||
|
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
||||||
result[0] = new TypeImpl(
|
result[0] = new TypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
typeConstructor,
|
typeConstructor,
|
||||||
nullable,
|
nullable,
|
||||||
resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()),
|
arguments,
|
||||||
classDescriptor.getMemberDomain()
|
classDescriptor.getMemberScope(arguments)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (type.getTypeArguments().isEmpty()) {
|
else if (type.getTypeArguments().isEmpty()) {
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class TypeScope implements JetScope {
|
|
||||||
private final Type receiverType;
|
|
||||||
|
|
||||||
public TypeScope(Type receiverType) {
|
|
||||||
this.receiverType = receiverType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Type getThisType() {
|
|
||||||
return receiverType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
|
||||||
return receiverType.getMemberDomain().getMethods(receiverType, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassDescriptor getClass(String name) {
|
|
||||||
return receiverType.getMemberDomain().getClassDescriptor(receiverType, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(String name) {
|
|
||||||
return receiverType.getMemberDomain().getProperty(receiverType, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
|
||||||
return receiverType.getMemberDomain().getExtension(receiverType, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class WritableScope implements JetScope {
|
||||||
|
private Map<String, PropertyDescriptor> propertyDescriptors;
|
||||||
|
|
||||||
|
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||||
|
if (propertyDescriptors == null) {
|
||||||
|
propertyDescriptors = new HashMap<String, PropertyDescriptor>();
|
||||||
|
}
|
||||||
|
assert !propertyDescriptors.containsKey(propertyDescriptor.getName()) : "Property redeclared";
|
||||||
|
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
return propertyDescriptors.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<MethodDescriptor> getMethods(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Type getThisType() {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,31 +1,34 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.SubstitutingScope;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ClassDescriptor extends MemberDescriptorImpl {
|
public class ClassDescriptor extends MemberDescriptorImpl {
|
||||||
private final TypeConstructor typeConstructor;
|
private final TypeConstructor typeConstructor;
|
||||||
private final TypeMemberDomain memberDomain;
|
private final JetScope memberDeclarations;
|
||||||
|
|
||||||
public ClassDescriptor(
|
public ClassDescriptor(
|
||||||
List<Attribute> attributes, boolean sealed,
|
List<Attribute> attributes, boolean sealed,
|
||||||
String name, List<TypeParameterDescriptor> typeParameters,
|
String name, List<TypeParameterDescriptor> typeParameters,
|
||||||
Collection<? extends Type> superclasses, TypeMemberDomain memberDomain) {
|
Collection<? extends Type> superclasses, JetScope memberDeclarations) {
|
||||||
super(attributes, name);
|
super(attributes, name);
|
||||||
this.typeConstructor = new TypeConstructor(attributes, sealed, name, typeParameters, superclasses);
|
this.typeConstructor = new TypeConstructor(attributes, sealed, name, typeParameters, superclasses);
|
||||||
this.memberDomain = memberDomain;
|
this.memberDeclarations = memberDeclarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassDescriptor(String name, TypeMemberDomain memberDomain) {
|
public ClassDescriptor(String name, JetScope memberDeclarations) {
|
||||||
this(Collections.<Attribute>emptyList(), true,
|
this(Collections.<Attribute>emptyList(), true,
|
||||||
name, Collections.<TypeParameterDescriptor>emptyList(),
|
name, Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
Collections.<Type>singleton(JetStandardClasses.getAnyType()), memberDomain);
|
Collections.<Type>singleton(JetStandardClasses.getAnyType()), memberDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -33,12 +36,8 @@ public class ClassDescriptor extends MemberDescriptorImpl {
|
|||||||
return typeConstructor;
|
return typeConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeMemberDomain getMemberDomain() {
|
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
|
||||||
return memberDomain;
|
Map<TypeConstructor,TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
|
||||||
|
return new SubstitutingScope(memberDeclarations, substitutionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassDescriptor getClass(String referencedName) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -10,25 +11,41 @@ import java.util.List;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ErrorType {
|
public class ErrorType {
|
||||||
private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() {
|
private static final JetScope ERROR_SCOPE = new JetScope() {
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name) {
|
public Collection<MethodDescriptor> getMethods(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassDescriptor getClass(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getProperty(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(String name) {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<MethodDescriptor> getMethods(Type contextType, String name) {
|
public Type getThisType() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -36,15 +53,15 @@ public class ErrorType {
|
|||||||
private ErrorType() {}
|
private ErrorType() {}
|
||||||
|
|
||||||
public static Type createErrorType(String debugMessage) {
|
public static Type createErrorType(String debugMessage) {
|
||||||
return createErrorType(debugMessage, ERROR_DOMAIN);
|
return createErrorType(debugMessage, ERROR_SCOPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type createErrorType(String debugMessage, TypeMemberDomain memberDomain) {
|
private static Type createErrorType(String debugMessage, JetScope memberScope) {
|
||||||
return new ErrorTypeImpl(new TypeConstructor(Collections.<Attribute>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.<Type>emptyList()), memberDomain);
|
return new ErrorTypeImpl(new TypeConstructor(Collections.<Attribute>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.<Type>emptyList()), memberScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type createWrongVarianceErrorType(TypeProjection value) {
|
public static Type createWrongVarianceErrorType(TypeProjection value) {
|
||||||
return createErrorType(value + " is not allowed here]", value.getType().getMemberDomain());
|
return createErrorType(value + " is not allowed here]", value.getType().getMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isErrorType(Type type) {
|
public static boolean isErrorType(Type type) {
|
||||||
@@ -54,11 +71,11 @@ public class ErrorType {
|
|||||||
private static class ErrorTypeImpl implements Type {
|
private static class ErrorTypeImpl implements Type {
|
||||||
|
|
||||||
private final TypeConstructor constructor;
|
private final TypeConstructor constructor;
|
||||||
private final TypeMemberDomain memberDomain;
|
private final JetScope memberScope;
|
||||||
|
|
||||||
private ErrorTypeImpl(TypeConstructor constructor, TypeMemberDomain memberDomain) {
|
private ErrorTypeImpl(TypeConstructor constructor, JetScope memberScope) {
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
this.memberDomain = memberDomain;
|
this.memberScope = memberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -80,8 +97,8 @@ public class ErrorType {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeMemberDomain getMemberDomain() {
|
public JetScope getMemberScope() {
|
||||||
return memberDomain;
|
return memberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
|
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -34,7 +35,7 @@ public class JetStandardClasses {
|
|||||||
public int size() {
|
public int size() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}, TypeMemberDomain.EMPTY
|
}, JetScope.EMPTY
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final ClassDescriptor ANY = new ClassDescriptor(
|
private static final ClassDescriptor ANY = new ClassDescriptor(
|
||||||
@@ -43,33 +44,12 @@ public class JetStandardClasses {
|
|||||||
"Any",
|
"Any",
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
Collections.<Type>emptySet(),
|
Collections.<Type>emptySet(),
|
||||||
TypeMemberDomain.EMPTY
|
JetScope.EMPTY
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final TypeMemberDomain STUB = new TypeMemberDomain() {
|
public static final JetScope STUB = JetScope.EMPTY;
|
||||||
@Override
|
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY);
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(Type contextType, String name) {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), TypeMemberDomain.EMPTY);
|
|
||||||
|
|
||||||
private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE);
|
private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE);
|
||||||
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte", STUB);
|
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte", STUB);
|
||||||
@@ -157,7 +137,7 @@ public class JetStandardClasses {
|
|||||||
getNothing().getTypeConstructor(),
|
getNothing().getTypeConstructor(),
|
||||||
true,
|
true,
|
||||||
Collections.<TypeProjection>emptyList(),
|
Collections.<TypeProjection>emptyList(),
|
||||||
TypeMemberDomain.EMPTY);
|
JetScope.EMPTY);
|
||||||
|
|
||||||
private static final Map<String, ClassDescriptor> CLASS_MAP = new HashMap<String, ClassDescriptor>();
|
private static final Map<String, ClassDescriptor> CLASS_MAP = new HashMap<String, ClassDescriptor>();
|
||||||
static {
|
static {
|
||||||
|
|||||||
@@ -233,9 +233,10 @@ public class JetTypeChecker {
|
|||||||
JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement();
|
JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement();
|
||||||
ClassDescriptor superclass = TypeResolver.INSTANCE.resolveClass(scope, typeElement);
|
ClassDescriptor superclass = TypeResolver.INSTANCE.resolveClass(scope, typeElement);
|
||||||
Collection<? extends Type> supertypes = thisType.getConstructor().getSupertypes();
|
Collection<? extends Type> supertypes = thisType.getConstructor().getSupertypes();
|
||||||
|
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(thisType);
|
||||||
for (Type declaredSupertype : supertypes) {
|
for (Type declaredSupertype : supertypes) {
|
||||||
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
|
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
|
||||||
result[0] = substituteInType(getSubstitutionContext(thisType), declaredSupertype, Variance.INVARIANT);
|
result[0] = TypeSubstitutor.INSTANCE.substitute(substitutionContext, declaredSupertype, Variance.INVARIANT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,13 +516,13 @@ public class JetTypeChecker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handler.beforeChildren(current);
|
handler.beforeChildren(current);
|
||||||
Map<TypeConstructor, TypeProjection> substitutionContext = getSubstitutionContext(current);
|
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(current);
|
||||||
for (Type supertype : current.getConstructor().getSupertypes()) {
|
for (Type supertype : current.getConstructor().getSupertypes()) {
|
||||||
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
||||||
if (visited.contains(supertypeConstructor)) {
|
if (visited.contains(supertypeConstructor)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Type substitutedSupertype = substituteInType(substitutionContext, supertype, Variance.INVARIANT);
|
Type substitutedSupertype = TypeSubstitutor.INSTANCE.substitute(substitutionContext, supertype, Variance.INVARIANT);
|
||||||
dfs(substitutedSupertype, visited, handler);
|
dfs(substitutedSupertype, visited, handler);
|
||||||
}
|
}
|
||||||
handler.afterChildren(current);
|
handler.afterChildren(current);
|
||||||
@@ -557,67 +558,12 @@ public class JetTypeChecker {
|
|||||||
for (Type immediateSupertype : constructor.getSupertypes()) {
|
for (Type immediateSupertype : constructor.getSupertypes()) {
|
||||||
Type correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype);
|
Type correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype);
|
||||||
if (correspondingSupertype != null) {
|
if (correspondingSupertype != null) {
|
||||||
return substituteInType(getSubstitutionContext(subtype), correspondingSupertype, Variance.INVARIANT);
|
return TypeSubstitutor.INSTANCE.substitute(subtype, correspondingSupertype, Variance.INVARIANT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<TypeConstructor, TypeProjection> getSubstitutionContext(Type context) {
|
|
||||||
Map<TypeConstructor, TypeProjection> parameterValues = new HashMap<TypeConstructor, TypeProjection>();
|
|
||||||
|
|
||||||
List<TypeParameterDescriptor> parameters = context.getConstructor().getParameters();
|
|
||||||
List<TypeProjection> contextArguments = context.getArguments();
|
|
||||||
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
|
||||||
TypeParameterDescriptor parameter = parameters.get(i);
|
|
||||||
TypeProjection value = contextArguments.get(i);
|
|
||||||
parameterValues.put(parameter.getTypeConstructor(), value);
|
|
||||||
}
|
|
||||||
return parameterValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Type substituteInType(Map<TypeConstructor, TypeProjection> substitutionContext, Type type, Variance howThisTypeIsUsed) {
|
|
||||||
TypeProjection value = substitutionContext.get(type.getConstructor());
|
|
||||||
if (value != null) {
|
|
||||||
Variance projectionKind = value.getProjectionKind();
|
|
||||||
if (howThisTypeIsUsed.allowsInPosition() && !projectionKind.allowsInPosition()
|
|
||||||
|| howThisTypeIsUsed.allowsOutPosition() && !projectionKind.allowsOutPosition()) {
|
|
||||||
return ErrorType.createWrongVarianceErrorType(value);
|
|
||||||
}
|
|
||||||
return value.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
return specializeType(type, substituteInArguments(substitutionContext, type));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private TypeProjection substitute(Map<TypeConstructor, TypeProjection> parameterValues, TypeProjection subject) {
|
|
||||||
@NotNull Type subjectType = subject.getType();
|
|
||||||
TypeProjection value = parameterValues.get(subjectType.getConstructor());
|
|
||||||
if (value != null) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
List<TypeProjection> newArguments = substituteInArguments(parameterValues, subjectType);
|
|
||||||
return new TypeProjection(subject.getProjectionKind(), specializeType(subjectType, newArguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TypeProjection> substituteInArguments(Map<TypeConstructor, TypeProjection> parameterValues, Type subjectType) {
|
|
||||||
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
|
||||||
for (TypeProjection argument : subjectType.getArguments()) {
|
|
||||||
newArguments.add(substitute(parameterValues, argument));
|
|
||||||
}
|
|
||||||
return newArguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Type substitute(@NotNull Type context, @NotNull Type subject, @NotNull Variance howThisTypeIsUsed) {
|
|
||||||
return substituteInType(getSubstitutionContext(context), subject, howThisTypeIsUsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Type specializeType(Type type, List<TypeProjection> newArguments) {
|
|
||||||
return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberDomain());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkSubtypeForTheSameConstructor(Type subtype, Type supertype) {
|
private boolean checkSubtypeForTheSameConstructor(Type subtype, Type supertype) {
|
||||||
TypeConstructor constructor = subtype.getConstructor();
|
TypeConstructor constructor = subtype.getConstructor();
|
||||||
assert constructor.equals(supertype.getConstructor());
|
assert constructor.equals(supertype.getConstructor());
|
||||||
@@ -636,7 +582,7 @@ public class JetTypeChecker {
|
|||||||
case INVARIANT:
|
case INVARIANT:
|
||||||
switch (superArgument.getProjectionKind()) {
|
switch (superArgument.getProjectionKind()) {
|
||||||
case INVARIANT:
|
case INVARIANT:
|
||||||
if (!equalTypes(subArgumentType, superArgumentType)) {
|
if (!TypeImpl.equalTypes(subArgumentType, superArgumentType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -688,9 +634,4 @@ public class JetTypeChecker {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equalTypes(@NotNull Type type1, @NotNull Type type2) {
|
|
||||||
return TypeImpl.equalTypes(type1, type2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class LazySubstitutedPropertyDescriptorImpl implements PropertyDescriptor {
|
public class LazySubstitutedPropertyDescriptorImpl implements PropertyDescriptor {
|
||||||
private final PropertyDescriptor propertyDescriptor;
|
private final PropertyDescriptor propertyDescriptor;
|
||||||
private final Type contextType;
|
private final Map<TypeConstructor, TypeProjection> substitutionContext;
|
||||||
private Type propertyType = null;
|
private Type propertyType = null;
|
||||||
|
|
||||||
public LazySubstitutedPropertyDescriptorImpl(PropertyDescriptor propertyDescriptor, Type contextType) {
|
public LazySubstitutedPropertyDescriptorImpl(@NotNull PropertyDescriptor propertyDescriptor, @NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||||
this.propertyDescriptor = propertyDescriptor;
|
this.propertyDescriptor = propertyDescriptor;
|
||||||
this.contextType = contextType;
|
this.substitutionContext = substitutionContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
if (propertyType == null) {
|
if (propertyType == null) {
|
||||||
propertyType = JetTypeChecker.INSTANCE.substitute(contextType, propertyDescriptor.getType(), Variance.OUT_VARIANCE);
|
propertyType = TypeSubstitutor.INSTANCE.substitute(substitutionContext, propertyDescriptor.getType(), Variance.OUT_VARIANCE);
|
||||||
}
|
}
|
||||||
return propertyType;
|
return propertyType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.modules.MemberDomain;
|
|
||||||
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -8,23 +7,19 @@ import java.util.Collection;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class NamespaceDescriptor implements NamespaceDomain, MemberDomain {
|
public class NamespaceDescriptor implements NamespaceDomain {
|
||||||
@Override
|
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(String name) {
|
public Collection<MethodDescriptor> getMethods(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -12,5 +13,6 @@ public interface Type extends Annotated {
|
|||||||
@NotNull List<TypeProjection> getArguments();
|
@NotNull List<TypeProjection> getArguments();
|
||||||
boolean isNullable();
|
boolean isNullable();
|
||||||
|
|
||||||
@NotNull TypeMemberDomain getMemberDomain();
|
@NotNull
|
||||||
|
JetScope getMemberScope();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -14,18 +15,18 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
|||||||
private final TypeConstructor constructor;
|
private final TypeConstructor constructor;
|
||||||
private final List<TypeProjection> arguments;
|
private final List<TypeProjection> arguments;
|
||||||
private final boolean nullable;
|
private final boolean nullable;
|
||||||
private final TypeMemberDomain memberDomain;
|
private JetScope memberScope;
|
||||||
|
|
||||||
public TypeImpl(List<Attribute> attributes, TypeConstructor constructor, boolean nullable, List<TypeProjection> arguments, TypeMemberDomain memberDomain) {
|
public TypeImpl(List<Attribute> attributes, TypeConstructor constructor, boolean nullable, List<TypeProjection> arguments, JetScope memberScope) {
|
||||||
super(attributes);
|
super(attributes);
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
this.nullable = nullable;
|
this.nullable = nullable;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.memberDomain = memberDomain;
|
this.memberScope = memberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeImpl(TypeConstructor constructor, TypeMemberDomain memberDomain) {
|
public TypeImpl(TypeConstructor constructor, JetScope memberScope) {
|
||||||
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberDomain);
|
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeImpl(ClassDescriptor classDescriptor) {
|
public TypeImpl(ClassDescriptor classDescriptor) {
|
||||||
@@ -33,7 +34,7 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
|||||||
classDescriptor.getTypeConstructor(),
|
classDescriptor.getTypeConstructor(),
|
||||||
false,
|
false,
|
||||||
Collections.<TypeProjection>emptyList(),
|
Collections.<TypeProjection>emptyList(),
|
||||||
classDescriptor.getMemberDomain());
|
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,8 +53,11 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeMemberDomain getMemberDomain() {
|
public JetScope getMemberScope() {
|
||||||
return memberDomain;
|
if (memberScope == null) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
return memberScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,7 +89,7 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
|||||||
// if (nullable != type.nullable) return false;
|
// if (nullable != type.nullable) return false;
|
||||||
// if (arguments != null ? !arguments.equals(type.arguments) : type.arguments != null) return false;
|
// if (arguments != null ? !arguments.equals(type.arguments) : type.arguments != null) return false;
|
||||||
// if (constructor != null ? !constructor.equals(type.constructor) : type.constructor != null) return false;
|
// if (constructor != null ? !constructor.equals(type.constructor) : type.constructor != null) return false;
|
||||||
// if (memberDomain != null ? !memberDomain.equals(type.memberDomain) : type.memberDomain != null) return false;
|
// if (memberScope != null ? !memberScope.equals(type.memberScope) : type.memberScope != null) return false;
|
||||||
|
|
||||||
// return true;
|
// return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public interface TypeMemberDomain {
|
|
||||||
TypeMemberDomain EMPTY = new TypeMemberDomain() {
|
|
||||||
@Override
|
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<MethodDescriptor> getMethods(Type contextType, String name) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getProperty(Type contextType, String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExtensionDescriptor getExtension(Type contextType, String name) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Collection<MethodDescriptor> getMethods(Type contextType, String name);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
PropertyDescriptor getProperty(Type contextType, String name);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ExtensionDescriptor getExtension(Type contextType, String name);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeSubstitutor {
|
||||||
|
public static final TypeSubstitutor INSTANCE = new TypeSubstitutor();
|
||||||
|
|
||||||
|
private TypeSubstitutor() {}
|
||||||
|
|
||||||
|
public Type substitute(@NotNull Type context, @NotNull Type subject, @NotNull Variance howThisTypeIsUsed) {
|
||||||
|
return substitute(getSubstitutionContext(context), subject, howThisTypeIsUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Type substitute(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext, @NotNull Type type, @NotNull Variance howThisTypeIsUsed) {
|
||||||
|
TypeProjection value = substitutionContext.get(type.getConstructor());
|
||||||
|
if (value != null) {
|
||||||
|
Variance projectionKind = value.getProjectionKind();
|
||||||
|
if (howThisTypeIsUsed.allowsInPosition() && !projectionKind.allowsInPosition()
|
||||||
|
|| howThisTypeIsUsed.allowsOutPosition() && !projectionKind.allowsOutPosition()) {
|
||||||
|
return ErrorType.createWrongVarianceErrorType(value);
|
||||||
|
}
|
||||||
|
return value.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
return specializeType(type, substituteInArguments(substitutionContext, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<TypeConstructor, TypeProjection> getSubstitutionContext(Type context) {
|
||||||
|
List<TypeParameterDescriptor> parameters = context.getConstructor().getParameters();
|
||||||
|
List<TypeProjection> contextArguments = context.getArguments();
|
||||||
|
|
||||||
|
return buildSubstitutionContext(parameters, contextArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<TypeConstructor, TypeProjection> buildSubstitutionContext(List<TypeParameterDescriptor> parameters, List<TypeProjection> contextArguments) {
|
||||||
|
Map<TypeConstructor, TypeProjection> parameterValues = new HashMap<TypeConstructor, TypeProjection>();
|
||||||
|
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
||||||
|
TypeParameterDescriptor parameter = parameters.get(i);
|
||||||
|
TypeProjection value = contextArguments.get(i);
|
||||||
|
parameterValues.put(parameter.getTypeConstructor(), value);
|
||||||
|
}
|
||||||
|
return parameterValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TypeProjection substituteInProjection(Map<TypeConstructor, TypeProjection> parameterValues, TypeProjection subject) {
|
||||||
|
@NotNull Type subjectType = subject.getType();
|
||||||
|
TypeProjection value = parameterValues.get(subjectType.getConstructor());
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
List<TypeProjection> newArguments = substituteInArguments(parameterValues, subjectType);
|
||||||
|
return new TypeProjection(subject.getProjectionKind(), specializeType(subjectType, newArguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TypeProjection> substituteInArguments(Map<TypeConstructor, TypeProjection> parameterValues, Type subjectType) {
|
||||||
|
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
|
||||||
|
for (TypeProjection argument : subjectType.getArguments()) {
|
||||||
|
newArguments.add(substituteInProjection(parameterValues, argument));
|
||||||
|
}
|
||||||
|
return newArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type specializeType(Type type, List<TypeProjection> newArguments) {
|
||||||
|
return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ public class TypeUtils {
|
|||||||
if (type.isNullable()) {
|
if (type.isNullable()) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return new TypeImpl(type.getAttributes(), type.getConstructor(), true, type.getArguments(), type.getMemberDomain());
|
return new TypeImpl(type.getAttributes(), type.getConstructor(), true, type.getArguments(), type.getMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
subtypes.add(makeType(type));
|
subtypes.add(makeType(type));
|
||||||
}
|
}
|
||||||
Type result = JetTypeChecker.INSTANCE.commonSupertype(subtypes);
|
Type result = JetTypeChecker.INSTANCE.commonSupertype(subtypes);
|
||||||
assertTrue(result + " != " + expected, JetTypeChecker.INSTANCE.equalTypes(result, makeType(expected)));
|
assertTrue(result + " != " + expected, TypeImpl.equalTypes(result, makeType(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
private static void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
||||||
@@ -366,7 +366,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
Project project = getProject();
|
Project project = getProject();
|
||||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
Type type = JetTypeChecker.INSTANCE.getType(ClassDefinitions.BASIC_SCOPE, jetExpression, false);
|
Type type = JetTypeChecker.INSTANCE.getType(ClassDefinitions.BASIC_SCOPE, jetExpression, false);
|
||||||
assertTrue(type + " != " + expectedType, JetTypeChecker.INSTANCE.equalTypes(type, expectedType));
|
assertTrue(type + " != " + expectedType, TypeImpl.equalTypes(type, expectedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertErrorType(String expression) {
|
private void assertErrorType(String expression) {
|
||||||
@@ -397,7 +397,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
|
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
|
||||||
Type expectedType = makeType(expectedTypeStr);
|
Type expectedType = makeType(expectedTypeStr);
|
||||||
assertTrue(type + " != " + expectedType, JetTypeChecker.INSTANCE.equalTypes(type, expectedType));
|
assertTrue(type + " != " + expectedType, TypeImpl.equalTypes(type, expectedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type makeType(String typeStr) {
|
private static Type makeType(String typeStr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user