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())
|
||||
: resolveTypes(typeParameterScope, delegationSpecifiers);
|
||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
||||
WritableScope members = resolveMembers(classElement, typeParameters, scope, typeParameterScope, superclasses);
|
||||
|
||||
return new ClassDescriptor(
|
||||
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
|
||||
!open,
|
||||
classElement.getName(),
|
||||
typeParameters,
|
||||
superclasses,
|
||||
resolveMemberDomain(classElement, scope, typeParameterScope, superclasses)
|
||||
members
|
||||
);
|
||||
}
|
||||
|
||||
private TypeMemberDomain resolveMemberDomain(
|
||||
private WritableScope resolveMembers(
|
||||
final JetClass classElement,
|
||||
List<TypeParameterDescriptor> typeParameters,
|
||||
final JetScope outerScope,
|
||||
final TypeParameterExtensibleScope typeParameterScope,
|
||||
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) {
|
||||
return substituteInPropertyDescriptor(contextType, resolvePropertyDescriptor(typeParameterScope, property));
|
||||
} else {
|
||||
// TODO : Caution: a cyclic dependency possible
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
WritableScope memberDeclarations = new WritableScope();
|
||||
|
||||
List<JetDeclaration> declarations = classElement.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
} else {
|
||||
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) {
|
||||
|
||||
@@ -2,16 +2,31 @@ package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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 java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface JetScope extends NamespaceDomain, MemberDomain {
|
||||
public interface JetScope {
|
||||
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
|
||||
TypeParameterDescriptor getTypeParameterDescriptor(String name);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
||||
|
||||
public ScopeWithReceiver(JetScope outerScope, Type receiverType) {
|
||||
this.outerScope = outerScope;
|
||||
this.receiverTypeScope = new TypeScope(receiverType);
|
||||
this.receiverTypeScope = receiverType.getMemberScope();
|
||||
}
|
||||
|
||||
@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);
|
||||
if (classDescriptor != null) {
|
||||
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
|
||||
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
|
||||
result[0] = new TypeImpl(
|
||||
attributes,
|
||||
typeConstructor,
|
||||
nullable,
|
||||
resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()),
|
||||
classDescriptor.getMemberDomain()
|
||||
arguments,
|
||||
classDescriptor.getMemberScope(arguments)
|
||||
);
|
||||
}
|
||||
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;
|
||||
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ClassDescriptor extends MemberDescriptorImpl {
|
||||
private final TypeConstructor typeConstructor;
|
||||
private final TypeMemberDomain memberDomain;
|
||||
private final JetScope memberDeclarations;
|
||||
|
||||
public ClassDescriptor(
|
||||
List<Attribute> attributes, boolean sealed,
|
||||
String name, List<TypeParameterDescriptor> typeParameters,
|
||||
Collection<? extends Type> superclasses, TypeMemberDomain memberDomain) {
|
||||
Collection<? extends Type> superclasses, JetScope memberDeclarations) {
|
||||
super(attributes, name);
|
||||
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,
|
||||
name, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<Type>singleton(JetStandardClasses.getAnyType()), memberDomain);
|
||||
Collections.<Type>singleton(JetStandardClasses.getAnyType()), memberDeclarations);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -33,12 +36,8 @@ public class ClassDescriptor extends MemberDescriptorImpl {
|
||||
return typeConstructor;
|
||||
}
|
||||
|
||||
public TypeMemberDomain getMemberDomain() {
|
||||
return memberDomain;
|
||||
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
|
||||
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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -10,25 +11,41 @@ import java.util.List;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ErrorType {
|
||||
private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() {
|
||||
private static final JetScope ERROR_SCOPE = new JetScope() {
|
||||
@NotNull
|
||||
@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
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@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) {
|
||||
public Type getThisType() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
};
|
||||
@@ -36,15 +53,15 @@ public class ErrorType {
|
||||
private ErrorType() {}
|
||||
|
||||
public static Type createErrorType(String debugMessage) {
|
||||
return createErrorType(debugMessage, ERROR_DOMAIN);
|
||||
return createErrorType(debugMessage, ERROR_SCOPE);
|
||||
}
|
||||
|
||||
private static Type createErrorType(String debugMessage, TypeMemberDomain memberDomain) {
|
||||
return new ErrorTypeImpl(new TypeConstructor(Collections.<Attribute>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.<Type>emptyList()), 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()), memberScope);
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -54,11 +71,11 @@ public class ErrorType {
|
||||
private static class ErrorTypeImpl implements Type {
|
||||
|
||||
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.memberDomain = memberDomain;
|
||||
this.memberScope = memberScope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -80,8 +97,8 @@ public class ErrorType {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeMemberDomain getMemberDomain() {
|
||||
return memberDomain;
|
||||
public JetScope getMemberScope() {
|
||||
return memberScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.JetScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -34,7 +35,7 @@ public class JetStandardClasses {
|
||||
public int size() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}, TypeMemberDomain.EMPTY
|
||||
}, JetScope.EMPTY
|
||||
);
|
||||
|
||||
private static final ClassDescriptor ANY = new ClassDescriptor(
|
||||
@@ -43,33 +44,12 @@ public class JetStandardClasses {
|
||||
"Any",
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<Type>emptySet(),
|
||||
TypeMemberDomain.EMPTY
|
||||
JetScope.EMPTY
|
||||
);
|
||||
|
||||
public static final TypeMemberDomain STUB = new TypeMemberDomain() {
|
||||
@Override
|
||||
public ClassDescriptor getClassDescriptor(@NotNull Type contextType, String name) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
public static final JetScope STUB = JetScope.EMPTY;
|
||||
|
||||
@NotNull
|
||||
@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 ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY);
|
||||
|
||||
private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE);
|
||||
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte", STUB);
|
||||
@@ -157,7 +137,7 @@ public class JetStandardClasses {
|
||||
getNothing().getTypeConstructor(),
|
||||
true,
|
||||
Collections.<TypeProjection>emptyList(),
|
||||
TypeMemberDomain.EMPTY);
|
||||
JetScope.EMPTY);
|
||||
|
||||
private static final Map<String, ClassDescriptor> CLASS_MAP = new HashMap<String, ClassDescriptor>();
|
||||
static {
|
||||
|
||||
@@ -233,9 +233,10 @@ public class JetTypeChecker {
|
||||
JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement();
|
||||
ClassDescriptor superclass = TypeResolver.INSTANCE.resolveClass(scope, typeElement);
|
||||
Collection<? extends Type> supertypes = thisType.getConstructor().getSupertypes();
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(thisType);
|
||||
for (Type declaredSupertype : supertypes) {
|
||||
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
|
||||
result[0] = substituteInType(getSubstitutionContext(thisType), declaredSupertype, Variance.INVARIANT);
|
||||
result[0] = TypeSubstitutor.INSTANCE.substitute(substitutionContext, declaredSupertype, Variance.INVARIANT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -515,13 +516,13 @@ public class JetTypeChecker {
|
||||
return;
|
||||
}
|
||||
handler.beforeChildren(current);
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = getSubstitutionContext(current);
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(current);
|
||||
for (Type supertype : current.getConstructor().getSupertypes()) {
|
||||
TypeConstructor supertypeConstructor = supertype.getConstructor();
|
||||
if (visited.contains(supertypeConstructor)) {
|
||||
continue;
|
||||
}
|
||||
Type substitutedSupertype = substituteInType(substitutionContext, supertype, Variance.INVARIANT);
|
||||
Type substitutedSupertype = TypeSubstitutor.INSTANCE.substitute(substitutionContext, supertype, Variance.INVARIANT);
|
||||
dfs(substitutedSupertype, visited, handler);
|
||||
}
|
||||
handler.afterChildren(current);
|
||||
@@ -557,67 +558,12 @@ public class JetTypeChecker {
|
||||
for (Type immediateSupertype : constructor.getSupertypes()) {
|
||||
Type correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype);
|
||||
if (correspondingSupertype != null) {
|
||||
return substituteInType(getSubstitutionContext(subtype), correspondingSupertype, Variance.INVARIANT);
|
||||
return TypeSubstitutor.INSTANCE.substitute(subtype, correspondingSupertype, Variance.INVARIANT);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
TypeConstructor constructor = subtype.getConstructor();
|
||||
assert constructor.equals(supertype.getConstructor());
|
||||
@@ -636,7 +582,7 @@ public class JetTypeChecker {
|
||||
case INVARIANT:
|
||||
switch (superArgument.getProjectionKind()) {
|
||||
case INVARIANT:
|
||||
if (!equalTypes(subArgumentType, superArgumentType)) {
|
||||
if (!TypeImpl.equalTypes(subArgumentType, superArgumentType)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -688,9 +634,4 @@ public class JetTypeChecker {
|
||||
}
|
||||
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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class LazySubstitutedPropertyDescriptorImpl implements PropertyDescriptor {
|
||||
private final PropertyDescriptor propertyDescriptor;
|
||||
private final Type contextType;
|
||||
private final Map<TypeConstructor, TypeProjection> substitutionContext;
|
||||
private Type propertyType = null;
|
||||
|
||||
public LazySubstitutedPropertyDescriptorImpl(PropertyDescriptor propertyDescriptor, Type contextType) {
|
||||
public LazySubstitutedPropertyDescriptorImpl(@NotNull PropertyDescriptor propertyDescriptor, @NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
this.contextType = contextType;
|
||||
this.substitutionContext = substitutionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.jet.lang.modules.MemberDomain;
|
||||
import org.jetbrains.jet.lang.modules.NamespaceDomain;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -8,23 +7,19 @@ import java.util.Collection;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class NamespaceDescriptor implements NamespaceDomain, MemberDomain {
|
||||
@Override
|
||||
public class NamespaceDescriptor implements NamespaceDomain {
|
||||
public ClassDescriptor getClass(String name) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MethodDescriptor> getMethods(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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -12,5 +13,6 @@ public interface Type extends Annotated {
|
||||
@NotNull List<TypeProjection> getArguments();
|
||||
boolean isNullable();
|
||||
|
||||
@NotNull TypeMemberDomain getMemberDomain();
|
||||
@NotNull
|
||||
JetScope getMemberScope();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@@ -14,18 +15,18 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
||||
private final TypeConstructor constructor;
|
||||
private final List<TypeProjection> arguments;
|
||||
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);
|
||||
this.constructor = constructor;
|
||||
this.nullable = nullable;
|
||||
this.arguments = arguments;
|
||||
this.memberDomain = memberDomain;
|
||||
this.memberScope = memberScope;
|
||||
}
|
||||
|
||||
public TypeImpl(TypeConstructor constructor, TypeMemberDomain memberDomain) {
|
||||
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberDomain);
|
||||
public TypeImpl(TypeConstructor constructor, JetScope memberScope) {
|
||||
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberScope);
|
||||
}
|
||||
|
||||
public TypeImpl(ClassDescriptor classDescriptor) {
|
||||
@@ -33,7 +34,7 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
||||
classDescriptor.getTypeConstructor(),
|
||||
false,
|
||||
Collections.<TypeProjection>emptyList(),
|
||||
classDescriptor.getMemberDomain());
|
||||
classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,8 +53,11 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMemberDomain getMemberDomain() {
|
||||
return memberDomain;
|
||||
public JetScope getMemberScope() {
|
||||
if (memberScope == null) {
|
||||
// TODO
|
||||
}
|
||||
return memberScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,7 +89,7 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
|
||||
// if (nullable != type.nullable) 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 (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;
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
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
|
||||
|
||||
@@ -335,7 +335,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
subtypes.add(makeType(type));
|
||||
}
|
||||
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) {
|
||||
@@ -366,7 +366,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
Project project = getProject();
|
||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||
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) {
|
||||
@@ -397,7 +397,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||
Type type = JetTypeChecker.INSTANCE.getType(scope, jetExpression, false);
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user