Refactoring: VariableDescriptors + substitution distributed across descriptor classes

This commit is contained in:
Andrey Breslav
2011-04-18 16:28:47 +04:00
parent fba0e8bc60
commit 9d79320b83
39 changed files with 476 additions and 210 deletions
@@ -187,8 +187,8 @@ public class ExpressionCodegen extends JetVisitor {
private void generateForInArray(JetForExpression expression, Type loopRangeType) {
final JetParameter loopParameter = expression.getLoopParameter();
final PropertyDescriptor parameterDescriptor = bindingContext.getParameterDescriptor(loopParameter);
JetType paramType = parameterDescriptor.getInType();
final VariableDescriptor parameterDescriptor = bindingContext.getParameterDescriptor(loopParameter);
JetType paramType = parameterDescriptor.getOutType();
Type asmParamType = typeMapper.mapType(paramType);
int lengthVar = myMap.enterTemp();
@@ -287,9 +287,9 @@ public class ExpressionCodegen extends JetVisitor {
for (JetElement statement : statements) {
if (statement instanceof JetProperty) {
final PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor((JetProperty) statement);
final Type type = typeMapper.mapType(propertyDescriptor.getOutType());
myMap.enter(propertyDescriptor, type.getSize());
final VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor((JetProperty) statement);
final Type type = typeMapper.mapType(variableDescriptor.getOutType());
myMap.enter(variableDescriptor, type.getSize());
}
}
@@ -309,10 +309,10 @@ public class ExpressionCodegen extends JetVisitor {
for (JetElement statement : statements) {
if (statement instanceof JetProperty) {
JetProperty var = (JetProperty) statement;
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(var);
Type outType = typeMapper.mapType(propertyDescriptor.getOutType());
VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor(var);
Type outType = typeMapper.mapType(variableDescriptor.getOutType());
int index = myMap.leave(propertyDescriptor);
int index = myMap.leave(variableDescriptor);
v.visitLocalVariable(var.getName(), outType.getDescriptor(), null, blockStart, blockEnd, index);
}
}
@@ -341,7 +341,7 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression(expression);
if (descriptor instanceof PropertyDescriptor) {
if (descriptor instanceof VariableDescriptor) {
final DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (isClass(container, "Number")) {
Type castType = getCastType(expression.getReferencedName());
@@ -367,7 +367,7 @@ public class ExpressionCodegen extends JetVisitor {
else {
int index = myMap.getIndex(descriptor);
if (index >= 0) {
final JetType outType = ((PropertyDescriptor) descriptor).getOutType();
final JetType outType = ((VariableDescriptor) descriptor).getOutType();
myStack.push(StackValue.local(index, typeMapper.mapType(outType)));
}
else {
@@ -923,14 +923,14 @@ public class ExpressionCodegen extends JetVisitor {
@Override
public void visitProperty(JetProperty property) {
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property);
int index = myMap.getIndex(propertyDescriptor);
VariableDescriptor variableDescriptor = bindingContext.getPropertyDescriptor(property);
int index = myMap.getIndex(variableDescriptor);
assert index >= 0;
JetExpression initializer = property.getInitializer();
if (initializer != null) {
Type type = typeMapper.mapType(propertyDescriptor.getOutType());
Type type = typeMapper.mapType(variableDescriptor.getOutType());
gen(initializer, type);
v.store(index, type);
}
@@ -12,8 +12,8 @@ public interface BindingContext {
ClassDescriptor getClassDescriptor(JetClass declaration);
TypeParameterDescriptor getTypeParameterDescriptor(JetTypeParameter declaration);
FunctionDescriptor getFunctionDescriptor(JetFunction declaration);
PropertyDescriptor getPropertyDescriptor(JetProperty declaration);
PropertyDescriptor getParameterDescriptor(JetParameter declaration);
VariableDescriptor getPropertyDescriptor(JetProperty declaration);
VariableDescriptor getParameterDescriptor(JetParameter declaration);
JetType getExpressionType(JetExpression expression);
@@ -112,13 +112,13 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
}
@Override
public PropertyDescriptor getPropertyDescriptor(JetProperty declaration) {
return (PropertyDescriptor) declarationsToDescriptors.get(declaration);
public VariableDescriptor getPropertyDescriptor(JetProperty declaration) {
return (VariableDescriptor) declarationsToDescriptors.get(declaration);
}
@Override
public PropertyDescriptor getParameterDescriptor(JetParameter declaration) {
return (PropertyDescriptor) declarationsToDescriptors.get(declaration);
public VariableDescriptor getParameterDescriptor(JetParameter declaration) {
return (VariableDescriptor) declarationsToDescriptors.get(declaration);
}
@Override
@@ -129,7 +129,7 @@ public class ClassDescriptorResolver {
@Override
public void visitProperty(JetProperty property) {
if (property.getPropertyTypeRef() != null) {
memberDeclarations.addPropertyDescriptor(resolvePropertyDescriptor(classDescriptor, typeParameterScope, property));
memberDeclarations.addVariableDescriptor(resolvePropertyDescriptor(classDescriptor, typeParameterScope, property));
} else {
// TODO : Caution: a cyclic dependency possible
throw new UnsupportedOperationException();
@@ -217,7 +217,7 @@ public class ClassDescriptorResolver {
result.add(valueParameterDescriptor);
trace.recordDeclarationResolution(valueParameter, valueParameterDescriptor);
parameterScope.addPropertyDescriptor(valueParameterDescriptor);
parameterScope.addVariableDescriptor(valueParameterDescriptor);
}
return result;
}
@@ -268,9 +268,9 @@ public class ClassDescriptorResolver {
}
@NotNull
public PropertyDescriptor resolveValueParameterDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, @NotNull JetParameter parameter) {
public VariableDescriptor resolveLocalVariableDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, @NotNull JetParameter parameter) {
JetType type = getParameterType(scope, parameter);
return resolveValueParameterDescriptor(containingDeclaration, parameter, type);
return resolveLocalVariableDescriptor(containingDeclaration, parameter, type);
}
private JetType getParameterType(JetScope scope, JetParameter parameter) {
@@ -286,18 +286,45 @@ public class ClassDescriptorResolver {
return type;
}
public PropertyDescriptor resolveValueParameterDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetParameter parameter, @NotNull JetType type) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptorImpl(
public VariableDescriptor resolveLocalVariableDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetParameter parameter, @NotNull JetType type) {
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()),
JetPsiUtil.safeName(parameter.getName()),
parameter.isMutable() ? null : type,
type);
trace.recordDeclarationResolution(parameter, propertyDescriptor);
type,
parameter.isMutable());
trace.recordDeclarationResolution(parameter, variableDescriptor);
return variableDescriptor;
}
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
JetType type = getType(scope, property);
VariableDescriptorImpl propertyDescriptor = new LocalVariableDescriptor(
containingDeclaration,
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
JetPsiUtil.safeName(property.getName()),
type,
property.isVar());
trace.recordDeclarationResolution(property, propertyDescriptor);
return propertyDescriptor;
}
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
public VariableDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
JetType type = getType(scope, property);
VariableDescriptorImpl propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
JetPsiUtil.safeName(property.getName()),
property.isVar() ? type : null,
type);
trace.recordDeclarationResolution(property, propertyDescriptor);
return propertyDescriptor;
}
@NotNull
private JetType getType(@NotNull JetScope scope, @NotNull JetProperty property) {
// TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
@@ -314,15 +341,7 @@ public class ClassDescriptorResolver {
} else {
type = typeResolver.resolveType(scope, propertyTypeRef);
}
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
containingDeclaration,
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
JetPsiUtil.safeName(property.getName()),
property.isVar() ? type : null,
type);
trace.recordDeclarationResolution(property, propertyDescriptor);
return propertyDescriptor;
return type;
}
@NotNull
@@ -372,13 +391,13 @@ public class ClassDescriptorResolver {
}
}
public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
public VariableDescriptor resolvePrimaryConstructorParameterToAProperty(
@NotNull ClassDescriptor classDescriptor,
@NotNull JetScope scope,
@NotNull JetParameter parameter) {
JetType type = getParameterType(scope, parameter);
String name = parameter.getName();
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
VariableDescriptorImpl propertyDescriptor = new PropertyDescriptor(
classDescriptor,
AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()),
name == null ? "<no name>" : name,
@@ -25,7 +25,7 @@ public interface JetScope {
NamespaceDescriptor getNamespace(@NotNull String name);
@Nullable
PropertyDescriptor getProperty(@NotNull String name);
VariableDescriptor getVariable(@NotNull String name);
@NotNull
FunctionGroup getFunctionGroup(@NotNull String name);
@@ -39,8 +39,8 @@ public class JetScopeAdapter implements JetScope {
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
return scope.getProperty(name);
public VariableDescriptor getVariable(@NotNull String name) {
return scope.getVariable(name);
}
@NotNull
@@ -16,7 +16,7 @@ public abstract class JetScopeImpl implements JetScope {
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
public VariableDescriptor getVariable(@NotNull String name) {
return null;
}
@@ -4,7 +4,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.*;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
@@ -12,17 +11,17 @@ import java.util.Map;
public class LazySubstitutingClassDescriptor implements ClassDescriptor {
private final ClassDescriptor original;
private final Map<TypeConstructor, TypeProjection> substitutionContext;
private final TypeSubstitutor substitutor;
public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, Map<TypeConstructor, TypeProjection> substitutionContext) {
public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) {
this.original = descriptor;
this.substitutionContext = substitutionContext;
this.substitutor = substitutor;
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
if (substitutionContext.isEmpty()) {
if (substitutor.isEmpty()) {
return original.getTypeConstructor();
}
throw new UnsupportedOperationException(); // TODO
@@ -32,10 +31,10 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
@Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
JetScope memberScope = original.getMemberScope(typeArguments);
if (substitutionContext.isEmpty()) {
if (substitutor.isEmpty()) {
return memberScope;
}
return new SubstitutingScope(memberScope, substitutionContext);
return new SubstitutingScope(memberScope, substitutor); // TODO : compose substitutors
}
@NotNull
@@ -73,6 +72,12 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
return original.getContainingDeclaration();
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
@@ -37,8 +37,8 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
Map<TypeConstructor,TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments);
return new SubstitutingScope(unsubstitutedMemberScope, substitutionContext);
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments);
return new SubstitutingScope(unsubstitutedMemberScope, TypeSubstitutor.create(substitutionContext));
}
@NotNull
@@ -62,7 +62,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
return constructors;
}
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments);
return new LazySubstitutingFunctionGroup(substitutionContext, constructors);
return new LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors);
}
@NotNull
@@ -75,6 +75,12 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
return classHeaderScope;
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
@@ -28,8 +28,8 @@ public class ScopeWithReceiver extends JetScopeImpl {
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
return receiverTypeScope.getProperty(name);
public VariableDescriptor getVariable(@NotNull String name) {
return receiverTypeScope.getVariable(name);
// TODO : extension properties
}
@@ -1,11 +1,9 @@
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
import java.util.Map;
/**
* @author abreslav
@@ -13,39 +11,22 @@ import java.util.Map;
public class SubstitutingScope implements JetScope {
private final JetScope workerScope;
private final Map<TypeConstructor, TypeProjection> substitutionContext;
// private final Map<TypeConstructor, TypeProjection> substitutionContext;
private final TypeSubstitutor substitutor;
public SubstitutingScope(JetScope workerScope, Map<TypeConstructor, TypeProjection> substitutionContext) {
public SubstitutingScope(JetScope workerScope, @NotNull TypeSubstitutor substitutor) {
this.workerScope = workerScope;
this.substitutionContext = substitutionContext;
this.substitutor = substitutor;
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
PropertyDescriptor property = workerScope.getProperty(name);
if (property == null || substitutionContext.isEmpty()) {
return property;
public VariableDescriptor getVariable(@NotNull String name) {
VariableDescriptor variable = workerScope.getVariable(name);
if (variable == null || substitutor.isEmpty()) {
return variable;
}
JetType inType = substitute(property.getInType(), Variance.IN_VARIANCE);
JetType outType = substitute(property.getOutType(), Variance.OUT_VARIANCE);
if (inType == null && outType == null) {
return null; // TODO : tell the user that the property was projected out
}
return new PropertyDescriptorImpl(
property.getContainingDeclaration(),
property.getAttributes(), // TODO
property.getName(),
inType,
outType
);
}
@Nullable
private JetType substitute(@Nullable JetType originalType, @NotNull Variance variance) {
if (originalType == null) return null;
return TypeSubstitutor.INSTANCE.substitute(substitutionContext, originalType, variance);
return variable.substitute(substitutor);
}
@Override
@@ -55,7 +36,7 @@ public class SubstitutingScope implements JetScope {
return null;
}
if (descriptor instanceof ClassDescriptor) {
return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutionContext);
return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutor);
}
throw new UnsupportedOperationException();
}
@@ -75,10 +56,10 @@ public class SubstitutingScope implements JetScope {
@Override
public FunctionGroup getFunctionGroup(@NotNull String name) {
FunctionGroup functionGroup = workerScope.getFunctionGroup(name);
if (substitutionContext.isEmpty()) {
if (substitutor.isEmpty()) {
return functionGroup;
}
return new LazySubstitutingFunctionGroup(substitutionContext, functionGroup);
return new LazySubstitutingFunctionGroup(substitutor, functionGroup);
}
@NotNull
@@ -211,12 +211,12 @@ public class TopDownAnalyzer {
WritableScope memberScope = classDescriptor.getUnsubstitutedMemberScope(); // TODO : this is REALLY questionable
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(memberScope, classDescriptor, klass);
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
classDescriptor,
memberScope,
parameter
);
memberScope.addPropertyDescriptor(
memberScope.addVariableDescriptor(
propertyDescriptor);
}
if (constructorDescriptor != null) {
@@ -240,8 +240,8 @@ public class TopDownAnalyzer {
private void processProperty(WritableScope declaringScope, JetProperty property) {
declaringScopes.put(property, declaringScope);
PropertyDescriptor descriptor = classDescriptorResolver.resolvePropertyDescriptor(declaringScope.getContainingDeclaration(), declaringScope, property);
declaringScope.addPropertyDescriptor(descriptor);
VariableDescriptor descriptor = classDescriptorResolver.resolvePropertyDescriptor(declaringScope.getContainingDeclaration(), declaringScope, property);
declaringScope.addVariableDescriptor(descriptor);
}
private void processClassObject(JetClassObject classObject) {
@@ -18,7 +18,7 @@ public class WritableScope extends JetScopeAdapter {
private final DeclarationDescriptor ownerDeclarationDescriptor;
@Nullable
private Map<String, PropertyDescriptor> propertyDescriptors;
private Map<String, VariableDescriptor> variableDescriptors;
@Nullable
private Map<String, WritableFunctionGroup> functionGroups;
@Nullable
@@ -93,37 +93,37 @@ public class WritableScope extends JetScopeAdapter {
}
@NotNull
private Map<String, PropertyDescriptor> getPropertyDescriptors() {
if (propertyDescriptors == null) {
propertyDescriptors = new HashMap<String, PropertyDescriptor>();
private Map<String, VariableDescriptor> getVariableDescriptors() {
if (variableDescriptors == null) {
variableDescriptors = new HashMap<String, VariableDescriptor>();
}
return propertyDescriptors;
return variableDescriptors;
}
public void addPropertyDescriptor(PropertyDescriptor propertyDescriptor) {
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
PropertyDescriptor existingDescriptor = propertyDescriptors.get(propertyDescriptor.getName());
public void addVariableDescriptor(VariableDescriptor variableDescriptor) {
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
VariableDescriptor existingDescriptor = propertyDescriptors.get(variableDescriptor.getName());
if (existingDescriptor != null) {
errorHandler.redeclaration(existingDescriptor, propertyDescriptor);
errorHandler.redeclaration(existingDescriptor, variableDescriptor);
}
// TODO : Should this always happen?
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
propertyDescriptors.put(variableDescriptor.getName(), variableDescriptor);
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
public VariableDescriptor getVariable(@NotNull String name) {
@NotNull
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
PropertyDescriptor propertyDescriptor = propertyDescriptors.get(name);
if (propertyDescriptor != null) {
return propertyDescriptor;
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
VariableDescriptor variableDescriptor = propertyDescriptors.get(name);
if (variableDescriptor != null) {
return variableDescriptor;
}
propertyDescriptor = super.getProperty(name);
if (propertyDescriptor != null) {
return propertyDescriptor;
variableDescriptor = super.getVariable(name);
if (variableDescriptor != null) {
return variableDescriptor;
}
for (JetScope imported : getImports()) {
PropertyDescriptor importedDescriptor = imported.getProperty(name);
VariableDescriptor importedDescriptor = imported.getVariable(name);
if (importedDescriptor != null) {
return importedDescriptor;
}
@@ -49,7 +49,7 @@ public class JavaClassMembersScope implements JetScope {
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
public VariableDescriptor getVariable(@NotNull String name) {
PsiField field = psiClass.findFieldByName(name, true);
if (field == null) return null;
if (field.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
@@ -57,7 +57,7 @@ public class JavaClassMembersScope implements JetScope {
}
JetType type = semanticServices.getTypeTransformer().transform(field.getType());
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
VariableDescriptorImpl propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
Collections.<Attribute>emptyList(),
field.getName(),
@@ -16,6 +16,12 @@ import java.util.*;
public class JavaDescriptorResolver {
/*package*/ static final DeclarationDescriptor JAVA_ROOT = new DeclarationDescriptorImpl(null, Collections.<Attribute>emptyList(), "<java_root>") {
@NotNull
@Override
public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
throw new UnsupportedOperationException(); // TODO
@@ -25,4 +25,8 @@ public interface ClassDescriptor extends ClassifierDescriptor {
*/
@NotNull
JetType getDefaultType();
@NotNull
@Override
ClassDescriptor substitute(TypeSubstitutor substitutor);
}
@@ -49,7 +49,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return memberDeclarations;
}
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
return new SubstitutingScope(memberDeclarations, substitutionContext);
return new SubstitutingScope(memberDeclarations, TypeSubstitutor.create(substitutionContext));
}
@NotNull
@@ -66,7 +66,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return constructors;
}
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(getTypeConstructor().getParameters(), typeArguments);
return new LazySubstitutingFunctionGroup(substitutionContext, constructors);
return new LazySubstitutingFunctionGroup(TypeSubstitutor.create(substitutionContext), constructors);
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
@@ -16,10 +16,11 @@ public interface DeclarationDescriptor extends Annotated, Named {
@NotNull
DeclarationDescriptor getOriginal();
@Nullable
DeclarationDescriptor getContainingDeclaration();
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor);
}
@@ -4,7 +4,7 @@ package org.jetbrains.jet.lang.types;
* @author abreslav
*/
public class DeclarationDescriptorVisitor<R, D> {
public R visitPropertyDescriptor(PropertyDescriptor descriptor, D data) {
public R visitVariableDescriptor(VariableDescriptor descriptor, D data) {
return null;
}
@@ -24,11 +24,23 @@ public class DeclarationDescriptorVisitor<R, D> {
return null;
}
public R visitModuleDeclaration(ModuleDescriptor moduleDescriptor, D data) {
public R visitModuleDeclaration(ModuleDescriptor descriptor, D data) {
return null;
}
public R visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data) {
return visitFunctionDescriptor(constructorDescriptor, data);
}
public R visitLocalVariableDescriptor(LocalVariableDescriptor descriptor, D data) {
return visitVariableDescriptor(descriptor, data);
}
public R visitPropertyDescriptor(PropertyDescriptor descriptor, D data) {
return visitVariableDescriptor(descriptor, data);
}
public R visitValueParameterDescriptor(ValueParameterDescriptor descriptor, D data) {
return visitVariableDescriptor(descriptor, data);
}
}
@@ -20,7 +20,7 @@ public class ErrorUtils {
}
@Override
public PropertyDescriptor getProperty(@NotNull String name) {
public VariableDescriptor getVariable(@NotNull String name) {
return ERROR_PROPERTY;
}
@@ -83,7 +83,7 @@ public class ErrorUtils {
}
private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
private static final PropertyDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(
private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptor(
ERROR_CLASS, Collections.<Attribute>emptyList(), "<ERROR PROPERTY>", ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
private static FunctionDescriptor createErrorFunction(List<TypeParameterDescriptor> typeParameters, List<JetType> positionedValueArgumentTypes) {
@@ -23,4 +23,7 @@ public interface FunctionDescriptor extends DeclarationDescriptor {
@Override
@NotNull
DeclarationDescriptor getContainingDeclaration();
@Override
FunctionDescriptor substitute(TypeSubstitutor substitutor);
}
@@ -71,6 +71,11 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return original;
}
@Override
public FunctionDescriptor substitute(TypeSubstitutor substitutor) {
return FunctionDescriptorUtil.substituteFunctionDescriptor(this, substitutor);
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitFunctionDescriptor(this, data);
@@ -58,13 +58,13 @@ public class FunctionDescriptorUtil {
}
@Nullable
private static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, Map<TypeConstructor, TypeProjection> substitutionContext) {
private static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getUnsubstitutedValueParameters();
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);
// TODO : Lazy?
JetType substitutedType = TypeSubstitutor.INSTANCE.substitute(substitutionContext, unsubstitutedValueParameter.getOutType(), Variance.IN_VARIANCE);
JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getOutType(), Variance.IN_VARIANCE);
if (substitutedType == null) return null;
result.add(new ValueParameterDescriptorImpl(
substitutedDescriptor,
@@ -81,19 +81,19 @@ public class FunctionDescriptorUtil {
}
@Nullable
private static JetType getSubstitutedReturnType(@NotNull FunctionDescriptor functionDescriptor, Map<TypeConstructor, TypeProjection> substitutionContext) {
return TypeSubstitutor.INSTANCE.substitute(substitutionContext, functionDescriptor.getUnsubstitutedReturnType(), Variance.OUT_VARIANCE);
private static JetType getSubstitutedReturnType(@NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) {
return substitutor.substitute(functionDescriptor.getUnsubstitutedReturnType(), Variance.OUT_VARIANCE);
}
@Nullable
public static FunctionDescriptor substituteFunctionDescriptor(@NotNull List<JetType> typeArguments, @NotNull FunctionDescriptor functionDescriptor) {
Map<TypeConstructor, TypeProjection> substitutionContext = createSubstitutionContext(functionDescriptor, typeArguments);
return substituteFunctionDescriptor(functionDescriptor, substitutionContext);
return substituteFunctionDescriptor(functionDescriptor, TypeSubstitutor.create(substitutionContext));
}
@Nullable
public static FunctionDescriptor substituteFunctionDescriptor(FunctionDescriptor functionDescriptor, Map<TypeConstructor, TypeProjection> substitutionContext) {
if (substitutionContext.isEmpty()) {
public static FunctionDescriptor substituteFunctionDescriptor(FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) {
if (substitutor.isEmpty()) {
return functionDescriptor;
}
FunctionDescriptorImpl substitutedDescriptor = new FunctionDescriptorImpl(
@@ -102,12 +102,12 @@ public class FunctionDescriptorUtil {
functionDescriptor.getAttributes(),
functionDescriptor.getName());
List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(substitutedDescriptor, functionDescriptor, substitutionContext);
List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(substitutedDescriptor, functionDescriptor, substitutor);
if (substitutedValueParameters == null) {
return null;
}
JetType substitutedReturnType = getSubstitutedReturnType(functionDescriptor, substitutionContext);
JetType substitutedReturnType = getSubstitutedReturnType(functionDescriptor, substitutor);
if (substitutedReturnType == null) {
return null;
}
@@ -127,7 +127,7 @@ public class FunctionDescriptorUtil {
parameterScope.addTypeParameterDescriptor(typeParameter);
}
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getUnsubstitutedValueParameters()) {
parameterScope.addPropertyDescriptor(valueParameterDescriptor);
parameterScope.addVariableDescriptor(valueParameterDescriptor);
}
parameterScope.addLabeledDeclaration(descriptor);
return parameterScope;
@@ -275,13 +275,14 @@ public class JetTypeChecker {
return;
}
handler.beforeChildren(current);
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(current);
// Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(current);
TypeSubstitutor substitutor = TypeSubstitutor.create(current);
for (JetType supertype : current.getConstructor().getSupertypes()) {
TypeConstructor supertypeConstructor = supertype.getConstructor();
if (visited.contains(supertypeConstructor)) {
continue;
}
JetType substitutedSupertype = TypeSubstitutor.INSTANCE.safeSubstitute(substitutionContext, supertype, Variance.INVARIANT);
JetType substitutedSupertype = substitutor.safeSubstitute(supertype, Variance.INVARIANT);
dfs(substitutedSupertype, visited, handler);
}
handler.afterChildren(current);
@@ -336,7 +337,7 @@ public class JetTypeChecker {
for (JetType immediateSupertype : constructor.getSupertypes()) {
JetType correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype);
if (correspondingSupertype != null) {
return TypeSubstitutor.INSTANCE.safeSubstitute(subtype, correspondingSupertype, Variance.INVARIANT);
return TypeSubstitutor.create(subtype).safeSubstitute(correspondingSupertype, Variance.INVARIANT);
}
}
return null;
@@ -442,12 +442,12 @@ public class JetTypeInferrer {
// TODO : type substitutions???
String referencedName = expression.getReferencedName();
if (referencedName != null) {
PropertyDescriptor property = scope.getProperty(referencedName);
if (property != null) {
trace.recordReferenceResolution(expression, property);
result = property.getOutType();
VariableDescriptor variable = scope.getVariable(referencedName);
if (variable != null) {
trace.recordReferenceResolution(expression, variable);
result = variable.getOutType();
if (result == null) {
semanticServices.getErrorHandler().genericError(expression.getNode(), "This property is not readable in this context");
semanticServices.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context");
}
return;
} else {
@@ -483,24 +483,24 @@ public class JetTypeInferrer {
}
List<JetElement> body = expression.getBody();
final Map<String, PropertyDescriptor> parameterDescriptors = new HashMap<String, PropertyDescriptor>();
final Map<String, VariableDescriptor> parameterDescriptors = new HashMap<String, VariableDescriptor>();
List<JetType> parameterTypes = new ArrayList<JetType>();
for (JetParameter parameter : expression.getParameters()) {
JetTypeReference typeReference = parameter.getTypeReference();
if (typeReference == null) {
throw new UnsupportedOperationException("Type inference for parameters is not implemented yet");
}
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, scope, parameter);
parameterDescriptors.put(parameter.getName(), propertyDescriptor);
parameterTypes.add(propertyDescriptor.getOutType());
VariableDescriptor variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(functionDescriptor, scope, parameter);
parameterDescriptors.put(parameter.getName(), variableDescriptor);
parameterTypes.add(variableDescriptor.getOutType());
}
JetType returnType;
if (returnTypeRef != null) {
returnType = typeResolver.resolveType(scope, returnTypeRef);
} else {
WritableScope writableScope = semanticServices.createWritableScope(scope, functionDescriptor);
for (PropertyDescriptor propertyDescriptor : parameterDescriptors.values()) {
writableScope.addPropertyDescriptor(propertyDescriptor);
for (VariableDescriptor variableDescriptor : parameterDescriptors.values()) {
writableScope.addVariableDescriptor(variableDescriptor);
}
writableScope.setThisType(receiverType);
returnType = getBlockReturnedType(writableScope, body);
@@ -702,10 +702,10 @@ public class JetTypeInferrer {
ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
Collection<? extends JetType> supertypes = thisType.getConstructor().getSupertypes();
Map<TypeConstructor, TypeProjection> substitutionContext = TypeUtils.buildSubstitutionContext(thisType);
TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
for (JetType declaredSupertype : supertypes) {
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
result = TypeSubstitutor.INSTANCE.safeSubstitute(substitutionContext, declaredSupertype, Variance.INVARIANT);
result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT);
break;
}
}
@@ -849,10 +849,10 @@ public class JetTypeInferrer {
if (loopParameter != null) {
JetTypeReference typeReference = loopParameter.getTypeReference();
PropertyDescriptor propertyDescriptor;
VariableDescriptor variableDescriptor;
if (typeReference != null) {
propertyDescriptor = classDescriptorResolver.resolveValueParameterDescriptor(scope.getContainingDeclaration(), scope, loopParameter);
JetType actualParameterType = propertyDescriptor.getOutType();
variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, loopParameter);
JetType actualParameterType = variableDescriptor.getOutType();
if (expectedParameterType != null &&
actualParameterType != null &&
!semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) {
@@ -863,9 +863,9 @@ public class JetTypeInferrer {
if (expectedParameterType == null) {
expectedParameterType = ErrorUtils.createErrorType("Error");
}
propertyDescriptor = classDescriptorResolver.resolveValueParameterDescriptor(scope.getContainingDeclaration(), loopParameter, expectedParameterType);
variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), loopParameter, expectedParameterType);
}
loopScope.addPropertyDescriptor(propertyDescriptor);
loopScope.addVariableDescriptor(variableDescriptor);
}
JetExpression body = expression.getBody();
@@ -926,7 +926,7 @@ public class JetTypeInferrer {
}
private boolean checkHasNextPropertySupport(@NotNull ASTNode reportErrorsOn, @NotNull JetType iteratorType) {
PropertyDescriptor hasNextProperty = iteratorType.getMemberScope().getProperty("hasNext");
VariableDescriptor hasNextProperty = iteratorType.getMemberScope().getVariable("hasNext");
// TODO :extension properties
if (hasNextProperty == null) {
return false;
@@ -1453,7 +1453,7 @@ public class JetTypeInferrer {
semanticServices.getErrorHandler().genericError(setter.getNode(), "Local variables are not allowed to have setters");
}
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(scope.getContainingDeclaration(), scope, property);
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property);
JetExpression initializer = property.getInitializer();
if (property.getPropertyTypeRef() != null && initializer != null) {
JetType initializerType = getType(scope, initializer, false);
@@ -1465,7 +1465,7 @@ public class JetTypeInferrer {
}
}
scope.addPropertyDescriptor(propertyDescriptor);
scope.addVariableDescriptor(propertyDescriptor);
}
@Override
@@ -7,17 +7,16 @@ import org.jetbrains.jet.lang.resolve.OverloadResolutionResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
*/
public class LazySubstitutingFunctionGroup implements FunctionGroup {
private final Map<TypeConstructor, TypeProjection> substitutionContext;
private final TypeSubstitutor substitutor;
private final FunctionGroup functionGroup;
public LazySubstitutingFunctionGroup(Map<TypeConstructor, TypeProjection> substitutionContext, FunctionGroup functionGroup) {
this.substitutionContext = substitutionContext;
public LazySubstitutingFunctionGroup(TypeSubstitutor substitutor, FunctionGroup functionGroup) {
this.substitutor = substitutor;
this.functionGroup = functionGroup;
}
@@ -35,7 +34,7 @@ public class LazySubstitutingFunctionGroup implements FunctionGroup {
Collection<FunctionDescriptor> result = new ArrayList<FunctionDescriptor>();
for (FunctionDescriptor function : resolutionResult.getFunctionDescriptors()) {
FunctionDescriptor functionDescriptor = substitute(substitutionContext, function);
FunctionDescriptor functionDescriptor = substitute(function);
if (functionDescriptor != null) {
result.add(functionDescriptor);
}
@@ -44,16 +43,11 @@ public class LazySubstitutingFunctionGroup implements FunctionGroup {
}
@Nullable
public FunctionDescriptor substitute(
@NotNull Map<TypeConstructor, TypeProjection> substitutionContext,
private FunctionDescriptor substitute(
@NotNull FunctionDescriptor functionDescriptor) {
if (substitutionContext.isEmpty()) return functionDescriptor;
if (substitutor.isEmpty()) return functionDescriptor;
FunctionDescriptor substituted = FunctionDescriptorUtil.substituteFunctionDescriptor(functionDescriptor, substitutionContext);
if (substituted == null) {
return null;
}
return substituted;
return functionDescriptor.substitute(substitutor);
}
@Override
@@ -0,0 +1,31 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author abreslav
*/
public class LocalVariableDescriptor extends VariableDescriptorImpl {
public LocalVariableDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Attribute> attributes,
@NotNull String name,
@Nullable JetType type,
boolean mutable) {
super(containingDeclaration, attributes, name, mutable ? type : null, type);
}
@NotNull
@Override
public LocalVariableDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitLocalVariableDescriptor(this, data);
}
}
@@ -4,4 +4,7 @@ package org.jetbrains.jet.lang.types;
* @author abreslav
*/
public interface MemberDescriptor {
boolean isAbstract();
boolean isVirtual();
boolean isOverride();
}
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
/**
@@ -10,6 +12,12 @@ public class ModuleDescriptor extends DeclarationDescriptorImpl {
super(null, Collections.<Attribute>emptyList(), name);
}
@NotNull
@Override
public ModuleDescriptor substitute(TypeSubstitutor substitutor) {
return this;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitModuleDeclaration(this, data);
@@ -35,6 +35,12 @@ public class NamespaceDescriptor extends DeclarationDescriptorImpl {
return namespaceType;
}
@NotNull
@Override
public NamespaceDescriptor substitute(TypeSubstitutor substitutor) {
return this;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitNamespaceDescriptor(this, data);
@@ -0,0 +1,81 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
/**
* @author abreslav
*/
public class PropertyAccessorDescriptor extends DeclarationDescriptorImpl implements FunctionDescriptor {
public enum AccessorType {
GETTER("get"),
SETTER("set");
private final String name;
AccessorType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static PropertyAccessorDescriptor createGetterDescriptor(
@NotNull PropertyDescriptor correspondingProperty,
@NotNull List<Attribute> attributes,
@NotNull JetType returnType
) {
return new PropertyAccessorDescriptor(correspondingProperty, attributes, AccessorType.GETTER);
}
public static PropertyAccessorDescriptor createSetterDescriptor(
@NotNull PropertyDescriptor correspondingProperty,
@NotNull List<Attribute> attributes,
@NotNull ValueParameterDescriptor parameter
) {
return new PropertyAccessorDescriptor(correspondingProperty, attributes, AccessorType.SETTER);
}
protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Attribute> attributes, @NotNull AccessorType accessorType) {
super(correspondingProperty.getContainingDeclaration(), attributes, accessorType.getName());
}
@NotNull
@Override
public PropertyAccessorDescriptor getOriginal() {
return (PropertyAccessorDescriptor) super.getOriginal();
}
@NotNull
@Override
public FunctionDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public List<TypeParameterDescriptor> getTypeParameters() {
return Collections.emptyList();
}
@NotNull
@Override
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public JetType getUnsubstitutedReturnType() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
throw new UnsupportedOperationException(); // TODO
}
}
@@ -3,24 +3,58 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author abreslav
*/
public interface PropertyDescriptor extends DeclarationDescriptor {
/**
* @return <code>null</code> for write-only variables (i.e. properties), variable value type otherwise
*/
@Nullable
JetType getOutType();
public class PropertyDescriptor extends VariableDescriptorImpl {
/**
* @return <code>null</code> for read-only variables (i.e. val's etc), or the type expected on assignment type otherwise
*/
@Nullable
JetType getInType();
private PropertyAccessorDescriptor getter;
private PropertyAccessorDescriptor setter;
private boolean hasBackingField;
public PropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Attribute> attributes,
@NotNull String name,
@Nullable JetType inType,
@Nullable JetType outType) {
super(containingDeclaration, attributes, name, inType, outType);
}
public PropertyAccessorDescriptor getGetter() {
return getter;
}
public PropertyAccessorDescriptor getSetter() {
return setter;
}
public boolean hasBackingFiled() {
return hasBackingField;
}
@NotNull
@Override
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
JetType originalInType = getInType();
JetType inType = originalInType == null ? null : substitutor.substitute(originalInType, Variance.IN_VARIANCE);
JetType outType = substitutor.substitute(getOutType(), Variance.OUT_VARIANCE);
if (inType == null && outType == null) {
return null; // TODO : tell the user that the property was projected out
}
return new PropertyDescriptor(
getContainingDeclaration(),
getAttributes(), // TODO
getName(),
inType,
outType
);
}
@Override
@SuppressWarnings({"NullableProblems"})
@NotNull
DeclarationDescriptor getContainingDeclaration();
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitPropertyDescriptor(this, data);
}
}
@@ -74,6 +74,12 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
return boundsAsType;
}
@NotNull
@Override
public TypeParameterDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTypeParameterDescriptor(this, data);
@@ -17,51 +17,71 @@ public class TypeSubstitutor {
}
}
public static final TypeSubstitutor INSTANCE = new TypeSubstitutor();
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
return new TypeSubstitutor(substitutionContext);
}
private TypeSubstitutor() {}
public static TypeSubstitutor create(@NotNull JetType context) {
return create(TypeUtils.buildSubstitutionContext(context));
}
public JetType safeSubstitute(@NotNull JetType context, @NotNull JetType subject, @NotNull Variance howThisTypeIsUsed) {
return safeSubstitute(TypeUtils.buildSubstitutionContext(context), subject, howThisTypeIsUsed);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private final @NotNull Map<TypeConstructor, TypeProjection> substitutionContext;
private TypeSubstitutor(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
this.substitutionContext = substitutionContext;
}
public boolean isEmpty() {
return substitutionContext.isEmpty();
}
@NotNull
public JetType safeSubstitute(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext, @NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
public JetType safeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
if (isEmpty()) {
return type;
}
try {
return unsafeSubstitute(substitutionContext, type, howThisTypeIsUsed);
return unsafeSubstitute(type, howThisTypeIsUsed);
} catch (SubstitutionException e) {
return ErrorUtils.createErrorType(e.getMessage());
}
}
@Nullable
public JetType substitute(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext, @NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
public JetType substitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) {
if (isEmpty()) {
return type;
}
try {
return unsafeSubstitute(substitutionContext, type, howThisTypeIsUsed);
return unsafeSubstitute(type, howThisTypeIsUsed);
} catch (SubstitutionException e) {
return null;
}
}
@NotNull
private JetType unsafeSubstitute(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext, @NotNull JetType type, @NotNull Variance howThisTypeIsUsed) throws SubstitutionException {
private JetType unsafeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) throws SubstitutionException {
TypeConstructor constructor = type.getConstructor();
TypeProjection value = substitutionContext.get(constructor);
if (value != null) {
assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor;
return substitutionResult(substitutionContext, (TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType();
//
return substitutionResult((TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType();
// if (!allows(howThisTypeIsUsed, value.getProjectionKind())) {
// throw new SubstitutionException("!!" + value.toString());
// }
// return value.getType();
}
return specializeType(type, substitutionContext, howThisTypeIsUsed);
return specializeType(type, howThisTypeIsUsed);
}
private JetType specializeType(JetType subjectType, Map<TypeConstructor, TypeProjection> substitutionContext, Variance callSiteVariance) throws SubstitutionException {
private JetType specializeType(JetType subjectType, Variance callSiteVariance) throws SubstitutionException {
List<TypeProjection> newArguments = new ArrayList<TypeProjection>();
List<TypeProjection> arguments = subjectType.getArguments();
for (int i = 0, argumentsSize = arguments.size(); i < argumentsSize; i++) {
@@ -78,7 +98,7 @@ public class TypeSubstitutor {
subjectType.getConstructor(),
subjectType.isNullable(),
newArguments,
new SubstitutingScope(subjectType.getMemberScope(), substitutionContext));
new SubstitutingScope(subjectType.getMemberScope(), this));
}
@NotNull
@@ -102,18 +122,16 @@ public class TypeSubstitutor {
return TypeUtils.makeStarProjection(correspondingTypeParameter);
}
return substitutionResult(substitutionContext, correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue);
return substitutionResult(correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue);
}
return new TypeProjection(
passedProjectionKind,
specializeType(
typeToSubstituteIn,
substitutionContext,
effectiveContextVariance));
}
private TypeProjection substitutionResult(
Map<TypeConstructor, TypeProjection> substitutionContext,
TypeParameterDescriptor correspondingTypeParameter,
Variance effectiveContextVariance,
Variance passedProjectionKind,
@@ -154,7 +172,7 @@ public class TypeSubstitutor {
// throw new SubstitutionException(""); // TODO : error message
// }
//
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, substitutionContext, effectiveContextVariance));
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, effectiveContextVariance));
}
private static Variance asymmetricOr(Variance a, Variance b) {
@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public interface ValueParameterDescriptor extends PropertyDescriptor {
public interface ValueParameterDescriptor extends VariableDescriptor {
/**
* Returns the 0-based index of the value parameter in the parameter list of its containing function.
*
@@ -8,7 +8,7 @@ import java.util.List;
/**
* @author abreslav
*/
public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl implements ValueParameterDescriptor {
public class ValueParameterDescriptorImpl extends VariableDescriptorImpl implements ValueParameterDescriptor {
private final boolean hasDefaultValue;
private final boolean isVararg;
private final int index;
@@ -53,4 +53,15 @@ public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl impleme
public boolean isVararg() {
return isVararg;
}
@NotNull
@Override
public VariableDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitValueParameterDescriptor(this, data);
}
}
@@ -0,0 +1,30 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author abreslav
*/
public interface VariableDescriptor extends DeclarationDescriptor {
/**
* @return <code>null</code> for write-only variables (i.e. properties), variable value type otherwise
*/
@Nullable
JetType getOutType();
/**
* @return <code>null</code> for read-only variables (i.e. val's etc), or the type expected on assignment type otherwise
*/
@Nullable
JetType getInType();
@Override
@SuppressWarnings({"NullableProblems"})
@NotNull
DeclarationDescriptor getContainingDeclaration();
@NotNull
@Override
VariableDescriptor substitute(TypeSubstitutor substitutor);
}
@@ -8,11 +8,11 @@ import java.util.List;
/**
* @author abreslav
*/
public class PropertyDescriptorImpl extends DeclarationDescriptorImpl implements PropertyDescriptor {
public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl implements VariableDescriptor {
private final JetType inType;
private final JetType outType;
public PropertyDescriptorImpl(
public VariableDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<Attribute> attributes,
@NotNull String name,
@@ -35,9 +35,4 @@ public class PropertyDescriptorImpl extends DeclarationDescriptorImpl implements
public JetType getInType() {
return inType;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitPropertyDescriptor(this, data);
}
}
@@ -17,7 +17,7 @@ public class DescriptorUtil {
declarationDescriptor.accept(
new DeclarationDescriptorVisitor<Void, StringBuilder>() {
@Override
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) {
JetType outType = descriptor.getOutType();
JetType inType = descriptor.getInType();
String typeString = "<no type>";
@@ -39,7 +39,7 @@ public class DescriptorUtil {
typeString = inType.toString();
}
builder.append(renderName(descriptor)).append(" : ").append(typeString);
return super.visitPropertyDescriptor(descriptor, builder);
return super.visitVariableDescriptor(descriptor, builder);
}
@Override
@@ -50,7 +50,7 @@ public class DescriptorUtil {
builder.append("(");
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getUnsubstitutedValueParameters().iterator(); iterator.hasNext(); ) {
ValueParameterDescriptor parameterDescriptor = iterator.next();
visitPropertyDescriptor(parameterDescriptor, builder);
visitVariableDescriptor(parameterDescriptor, builder);
if (iterator.hasNext()) {
builder.append(", ");
}