Working on resolve for properties

This commit is contained in:
Andrey Breslav
2011-02-08 20:22:19 +03:00
parent 4818007291
commit 39b4392987
14 changed files with 378 additions and 113 deletions
@@ -1,17 +1,20 @@
package org.jetbrains.jet.lang.modules; package org.jetbrains.jet.lang.modules;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.types.ClassDescriptor; import org.jetbrains.jet.lang.types.ClassDescriptor;
import org.jetbrains.jet.lang.types.ExtensionDescriptor; import org.jetbrains.jet.lang.types.ExtensionDescriptor;
import org.jetbrains.jet.lang.types.MethodDescriptor; import org.jetbrains.jet.lang.types.MethodDescriptor;
import org.jetbrains.jet.lang.types.PropertyDescriptor; import org.jetbrains.jet.lang.types.PropertyDescriptor;
import java.util.Collection;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface MemberDomain { public interface MemberDomain {
@Nullable @NotNull
MethodDescriptor getMethods(String name); Collection<MethodDescriptor> getMethods(String name);
@Nullable @Nullable
ClassDescriptor getClass(String name); ClassDescriptor getClass(String name);
@@ -18,27 +18,84 @@ public class ClassDescriptorResolver {
@Nullable @Nullable
public ClassDescriptor resolveClassDescriptor(@NotNull JetScope scope, @NotNull JetClass classElement) { public ClassDescriptor resolveClassDescriptor(@NotNull JetScope scope, @NotNull JetClass classElement) {
TypeParameterExtensibleScope extensibleScope = new TypeParameterExtensibleScope(scope); TypeParameterExtensibleScope typeParameterScope = new TypeParameterExtensibleScope(scope);
// This call has side-effects on the extensibleScope (fills it in) // This call has side-effects on the typeParameterScope (fills it in)
List<TypeParameterDescriptor> typeParameters List<TypeParameterDescriptor> typeParameters
= resolveTypeParameters(extensibleScope, classElement.getTypeParameters()); = resolveTypeParameters(typeParameterScope, classElement.getTypeParameters());
List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers(); List<JetDelegationSpecifier> delegationSpecifiers = classElement.getDelegationSpecifiers();
// TODO : assuming that the hierarchy is acyclic
Collection<? extends Type> superclasses = delegationSpecifiers.isEmpty() Collection<? extends Type> superclasses = delegationSpecifiers.isEmpty()
? Collections.singleton(JetStandardClasses.getAnyType()) ? Collections.singleton(JetStandardClasses.getAnyType())
: resolveTypes(extensibleScope, delegationSpecifiers); : resolveTypes(typeParameterScope, delegationSpecifiers);
boolean open = classElement.getModifierList().hasModifier(JetTokens.OPEN_KEYWORD); boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
return new ClassDescriptor( return new ClassDescriptor(
AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()), AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()),
!open, !open,
classElement.getName(), classElement.getName(),
typeParameters, typeParameters,
superclasses superclasses,
resolveMemberDomain(classElement, scope, typeParameterScope, superclasses)
); );
} }
private TypeMemberDomain resolveMemberDomain(
final JetClass classElement,
final JetScope outerScope,
final TypeParameterExtensibleScope typeParameterScope,
final Collection<? extends Type> supertypes) {
// TODO : Cache!!!
return new TypeMemberDomain() {
@Override
public PropertyDescriptor getProperty(Type receiverType, @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;
// TODO : Caution: a cyclic dependency possible
if (property.getPropertyTypeRef() != null) {
return resolvePropertyDescriptor(JetScope.EMPTY, property);
} else {
throw new UnsupportedOperationException();
}
}
}
for (Type supertype : supertypes) {
PropertyDescriptor property = supertype.getMemberDomain().getProperty(JetTypeChecker.INSTANCE.substitute(receiverType, supertype), name);
if (property != null) {
return property;
}
}
return null;
}
@Override
public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public Collection<MethodDescriptor> getMethods(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public ExtensionDescriptor getExtension(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO
}
};
}
private static List<TypeParameterDescriptor> resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) { private static List<TypeParameterDescriptor> resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List<JetTypeParameter> typeParameters) {
// TODO : When-clause
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>(); List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
for (JetTypeParameter typeParameter : typeParameters) { for (JetTypeParameter typeParameter : typeParameters) {
result.add(resolveTypeParameter(extensibleScope, typeParameter)); result.add(resolveTypeParameter(extensibleScope, typeParameter));
@@ -76,31 +133,6 @@ public class ClassDescriptorResolver {
return TypeResolver.INSTANCE.resolveType(scope, typeReference); return TypeResolver.INSTANCE.resolveType(scope, typeReference);
} }
private static final class TypeParameterExtensibleScope extends JetScopeAdapter {
private final Map<String, TypeParameterDescriptor> typeParameterDescriptors = new HashMap<String, TypeParameterDescriptor>();
private TypeParameterExtensibleScope(JetScope scope) {
super(scope);
}
public void addTypeParameterDescriptor(TypeParameterDescriptor typeParameterDescriptor) {
String name = typeParameterDescriptor.getName();
if (typeParameterDescriptors.containsKey(name)) {
throw new UnsupportedOperationException(); // TODO
}
typeParameterDescriptors.put(name, typeParameterDescriptor);
}
@Override
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptors.get(name);
if (typeParameterDescriptor != null) {
return typeParameterDescriptor;
}
return super.getTypeParameterDescriptor(name);
}
}
@NotNull @NotNull
public PropertyDescriptor resolvePropertyDescriptor(@NotNull JetScope scope, @NotNull JetParameter parameter) { public PropertyDescriptor resolvePropertyDescriptor(@NotNull JetScope scope, @NotNull JetParameter parameter) {
return new PropertyDescriptor( return new PropertyDescriptor(
@@ -128,4 +160,30 @@ public class ClassDescriptorResolver {
property.getName(), property.getName(),
type); type);
} }
private static final class TypeParameterExtensibleScope extends JetScopeAdapter {
private final Map<String, TypeParameterDescriptor> typeParameterDescriptors = new HashMap<String, TypeParameterDescriptor>();
private TypeParameterExtensibleScope(JetScope scope) {
super(scope);
}
public void addTypeParameterDescriptor(TypeParameterDescriptor typeParameterDescriptor) {
String name = typeParameterDescriptor.getName();
if (typeParameterDescriptors.containsKey(name)) {
throw new UnsupportedOperationException(); // TODO
}
typeParameterDescriptors.put(name, typeParameterDescriptor);
}
@Override
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptors.get(name);
if (typeParameterDescriptor != null) {
return typeParameterDescriptor;
}
return super.getTypeParameterDescriptor(name);
}
}
} }
@@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
/** /**
* @author abreslav * @author abreslav
*/ */
@@ -30,7 +32,7 @@ public class JetScopeAdapter implements JetScope {
} }
@Override @Override
public MethodDescriptor getMethods(String name) { public Collection<MethodDescriptor> getMethods(String name) {
return scope.getMethods(name); return scope.getMethods(name);
} }
@@ -1,14 +1,19 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import java.util.Collection;
import java.util.Collections;
/** /**
* @author abreslav * @author abreslav
*/ */
public abstract class JetScopeImpl implements JetScope { public abstract class JetScopeImpl implements JetScope {
@Override @Override
public MethodDescriptor getMethods(String name) { @NotNull
return null; public Collection<MethodDescriptor> getMethods(String name) {
return Collections.emptyList();
} }
@Override @Override
@@ -36,6 +41,7 @@ public abstract class JetScopeImpl implements JetScope {
return null; return null;
} }
@NotNull
@Override @Override
public Type getThisType() { public Type getThisType() {
return JetStandardClasses.getNothingType(); return JetStandardClasses.getNothingType();
@@ -0,0 +1,63 @@
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 ScopeWithReceiver extends JetScopeImpl {
private final JetScope receiverTypeScope;
private final JetScope outerScope;
public ScopeWithReceiver(JetScope outerScope, Type receiverType) {
this.outerScope = outerScope;
this.receiverTypeScope = new TypeScope(receiverType);
}
@Override
public Collection<MethodDescriptor> getMethods(String name) {
return receiverTypeScope.getMethods(name);
// TODO : Extension methods
// Collection<MethodDescriptor> outerScopeMethods = outerScope.getMethods(name);
// for (MethodDescriptor method : outerScopeMethods) {
// check for extensions for receiver type
// method.hasReceiver()
// }
}
@Override
public ClassDescriptor getClass(String name) {
return super.getClass(name); // TODO
}
@Override
public PropertyDescriptor getProperty(String name) {
return receiverTypeScope.getProperty(name);
// TODO : extension properties
}
@Override
public ExtensionDescriptor getExtension(String name) {
return super.getExtension(name); // TODO
}
@Override
public NamespaceDescriptor getNamespace(String name) {
return outerScope.getNamespace(name);
}
@Override
public TypeParameterDescriptor getTypeParameterDescriptor(String name) {
return outerScope.getTypeParameterDescriptor(name);
}
@NotNull
@Override
public Type getThisType() {
return receiverTypeScope.getThisType();
}
}
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.modules.MemberDomain;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -162,15 +161,16 @@ public class TypeResolver {
if (qualifier != null) { if (qualifier != null) {
// TODO: this is slow. The faster way would be to start with the first item in the qualified name // TODO: this is slow. The faster way would be to start with the first item in the qualified name
// TODO: priorities: class of namespace first? // TODO: priorities: class of namespace first?
MemberDomain domain = resolveClass(scope, qualifier); throw new UnsupportedOperationException();
if (domain == null) { // MemberDomain domain = resolveClass(scope, qualifier);
domain = resolveNamespace(scope, qualifier); // if (domain == null) {
} // domain = resolveNamespace(scope, qualifier);
// }
if (domain != null) { //
return domain.getClass(expression.getReferencedName()); // if (domain != null) {
} // return domain.getClass(expression.getReferencedName());
return null; // }
// return null;
} }
assert qualifier == null; assert qualifier == null;
@@ -0,0 +1,53 @@
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;
}
}
@@ -1,7 +1,6 @@
package org.jetbrains.jet.lang.types; package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.modules.MemberDomain;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -10,20 +9,23 @@ import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public class ClassDescriptor extends MemberDescriptorImpl implements MemberDomain { public class ClassDescriptor extends MemberDescriptorImpl {
private final TypeConstructor typeConstructor; private final TypeConstructor typeConstructor;
private final TypeMemberDomain memberDomain;
public ClassDescriptor( public ClassDescriptor(
List<Attribute> attributes, boolean sealed, List<Attribute> attributes, boolean sealed,
String name, List<TypeParameterDescriptor> typeParameters, Collection<? extends Type> superclasses) { String name, List<TypeParameterDescriptor> typeParameters,
Collection<? extends Type> superclasses, TypeMemberDomain memberDomain) {
super(attributes, name); super(attributes, name);
this.typeConstructor = new TypeConstructor(attributes, sealed, name, typeParameters, superclasses); this.typeConstructor = new TypeConstructor(attributes, sealed, name, typeParameters, superclasses);
this.memberDomain = memberDomain;
} }
public ClassDescriptor(String name) { public ClassDescriptor(String name, TypeMemberDomain memberDomain) {
this(Collections.<Attribute>emptyList(), true, this(Collections.<Attribute>emptyList(), true,
name, Collections.<TypeParameterDescriptor>emptyList(), name, Collections.<TypeParameterDescriptor>emptyList(),
Collections.<Type>singleton(JetStandardClasses.getAnyType())); Collections.<Type>singleton(JetStandardClasses.getAnyType()), memberDomain);
} }
@NotNull @NotNull
@@ -31,22 +33,12 @@ public class ClassDescriptor extends MemberDescriptorImpl implements MemberDomai
return typeConstructor; return typeConstructor;
} }
public TypeMemberDomain getMemberDomain() {
return memberDomain;
}
public ClassDescriptor getClass(String referencedName) { public ClassDescriptor getClass(String referencedName) {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
@Override }
public 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
}
}
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
/** /**
@@ -10,7 +11,23 @@ import java.util.Collections;
public class ErrorType { public class ErrorType {
private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() { private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() {
@Override @Override
public ClassDescriptor getClassDescriptor(@NotNull Type type) { public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public Collection<MethodDescriptor> getMethods(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public PropertyDescriptor getProperty(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public ExtensionDescriptor getExtension(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
}; };
@@ -34,7 +34,7 @@ public class JetStandardClasses {
public int size() { public int size() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }, TypeMemberDomain.EMPTY
); );
private static final ClassDescriptor ANY = new ClassDescriptor( private static final ClassDescriptor ANY = new ClassDescriptor(
@@ -42,24 +42,50 @@ public class JetStandardClasses {
false, false,
"Any", "Any",
Collections.<TypeParameterDescriptor>emptyList(), Collections.<TypeParameterDescriptor>emptyList(),
Collections.<Type>emptySet() Collections.<Type>emptySet(),
TypeMemberDomain.EMPTY
); );
private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), TypeMemberDomain.EMPTY); public static final TypeMemberDomain STUB = new TypeMemberDomain() {
private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE); @Override
public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) {
throw new UnsupportedOperationException(); // TODO
}
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte"); @NotNull
private static final ClassDescriptor CHAR = new ClassDescriptor("Char"); @Override
private static final ClassDescriptor SHORT = new ClassDescriptor("Short"); public Collection<MethodDescriptor> getMethods(Type receiverType, String name) {
private static final ClassDescriptor INT = new ClassDescriptor("Int"); throw new UnsupportedOperationException(); // TODO
private static final ClassDescriptor LONG = new ClassDescriptor("Long"); }
private static final ClassDescriptor FLOAT = new ClassDescriptor("Float");
private static final ClassDescriptor DOUBLE = new ClassDescriptor("Double"); @Override
private static final ClassDescriptor BOOLEAN = new ClassDescriptor("Boolean"); public PropertyDescriptor getProperty(Type receiverType, String name) {
private static final ClassDescriptor STRING = new ClassDescriptor("String"); throw new UnsupportedOperationException(); // TODO
}
@Override
public ExtensionDescriptor getExtension(Type receiverType, String name) {
throw new UnsupportedOperationException(); // TODO
}
};
private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), TypeMemberDomain.EMPTY);
private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE);
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte", STUB);
private static final ClassDescriptor CHAR = new ClassDescriptor("Char", STUB);
private static final ClassDescriptor SHORT = new ClassDescriptor("Short", STUB);
private static final ClassDescriptor INT = new ClassDescriptor("Int", STUB);
private static final ClassDescriptor LONG = new ClassDescriptor("Long", STUB);
private static final ClassDescriptor FLOAT = new ClassDescriptor("Float", STUB);
private static final ClassDescriptor DOUBLE = new ClassDescriptor("Double", STUB);
private static final ClassDescriptor BOOLEAN = new ClassDescriptor("Boolean", STUB);
private static final ClassDescriptor STRING = new ClassDescriptor("String", STUB);
public static final int TUPLE_COUNT = 22; public static final int TUPLE_COUNT = 22;
private static final ClassDescriptor[] TUPLE = new ClassDescriptor[TUPLE_COUNT]; private static final ClassDescriptor[] TUPLE = new ClassDescriptor[TUPLE_COUNT];
static { static {
for (int i = 0; i < TUPLE_COUNT; i++) { for (int i = 0; i < TUPLE_COUNT; i++) {
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(); List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
@@ -74,13 +100,14 @@ public class JetStandardClasses {
true, true,
"Tuple" + i, "Tuple" + i,
parameters, parameters,
Collections.singleton(JetStandardClasses.getAnyType())); Collections.singleton(JetStandardClasses.getAnyType()), STUB);
} }
} }
public static final int FUNCTION_COUNT = 22; public static final int FUNCTION_COUNT = 22;
private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[FUNCTION_COUNT];
private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[FUNCTION_COUNT];
static { static {
for (int i = 0; i < FUNCTION_COUNT; i++) { for (int i = 0; i < FUNCTION_COUNT; i++) {
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(); List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
@@ -99,7 +126,7 @@ public class JetStandardClasses {
false, false,
"Function" + i, "Function" + i,
parameters, parameters,
Collections.singleton(JetStandardClasses.getAnyType())); Collections.singleton(JetStandardClasses.getAnyType()), STUB);
parameters.add(0, new TypeParameterDescriptor( parameters.add(0, new TypeParameterDescriptor(
Collections.<Attribute>emptyList(), Collections.<Attribute>emptyList(),
Variance.IN_VARIANCE, "T", Variance.IN_VARIANCE, "T",
@@ -109,29 +136,22 @@ public class JetStandardClasses {
false, false,
"ReceiverFunction" + i, "ReceiverFunction" + i,
parameters, parameters,
Collections.singleton(JetStandardClasses.getAnyType())); Collections.singleton(JetStandardClasses.getAnyType()), STUB);
} }
} }
private static final Type BYTE_TYPE = new TypeImpl(getByte());
private static final Type CHAR_TYPE = new TypeImpl(getChar());
private static final Type SHORT_TYPE = new TypeImpl(getShort());
private static final Type INT_TYPE = new TypeImpl(getInt());
private static final Type LONG_TYPE = new TypeImpl(getLong());
private static final Type FLOAT_TYPE = new TypeImpl(getFloat());
private static final Type DOUBLE_TYPE = new TypeImpl(getDouble());
private static final Type BOOLEAN_TYPE = new TypeImpl(getBoolean());
private static final Type STRING_TYPE = new TypeImpl(getString());
private static final Type UNIT_TYPE = new TypeImpl(getTuple(0));
private static final Type NOTHING_TYPE = new TypeImpl(getNothing());
public static final TypeMemberDomain STUB = new TypeMemberDomain() {
@Override
public ClassDescriptor getClassDescriptor(@NotNull Type type) {
throw new UnsupportedOperationException(); // TODO
}
};
private static final Type BYTE_TYPE = new TypeImpl(getByte().getTypeConstructor(), STUB);
private static final Type CHAR_TYPE = new TypeImpl(getChar().getTypeConstructor(), STUB);
private static final Type SHORT_TYPE = new TypeImpl(getShort().getTypeConstructor(), STUB);
private static final Type INT_TYPE = new TypeImpl(getInt().getTypeConstructor(), STUB);
private static final Type LONG_TYPE = new TypeImpl(getLong().getTypeConstructor(), STUB);
private static final Type FLOAT_TYPE = new TypeImpl(getFloat().getTypeConstructor(), STUB);
private static final Type DOUBLE_TYPE = new TypeImpl(getDouble().getTypeConstructor(), STUB);
private static final Type BOOLEAN_TYPE = new TypeImpl(getBoolean().getTypeConstructor(), STUB);
private static final Type STRING_TYPE = new TypeImpl(getString().getTypeConstructor(), STUB);
private static final Type UNIT_TYPE = new TypeImpl(getTuple(0).getTypeConstructor(), STUB);
private static final Type NOTHING_TYPE = new TypeImpl(getNothing().getTypeConstructor(), STUB);
private static final Type NULLABLE_NOTHING_TYPE = new TypeImpl( private static final Type NULLABLE_NOTHING_TYPE = new TypeImpl(
Collections.<Attribute>emptyList(), Collections.<Attribute>emptyList(),
getNothing().getTypeConstructor(), getNothing().getTypeConstructor(),
@@ -53,11 +53,11 @@ public class JetTypeChecker {
JetTypeReference returnTypeRef = expression.getReturnTypeRef(); JetTypeReference returnTypeRef = expression.getReturnTypeRef();
JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); JetTypeReference receiverTypeRef = expression.getReceiverTypeRef();
final Type thisType; final Type receiverType;
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
thisType = TypeResolver.INSTANCE.resolveType(scope, receiverTypeRef); receiverType = TypeResolver.INSTANCE.resolveType(scope, receiverTypeRef);
} else { } else {
thisType = scope.getThisType(); receiverType = scope.getThisType();
} }
List<JetElement> body = expression.getBody(); List<JetElement> body = expression.getBody();
@@ -77,9 +77,10 @@ public class JetTypeChecker {
returnType = TypeResolver.INSTANCE.resolveType(scope, returnTypeRef); returnType = TypeResolver.INSTANCE.resolveType(scope, returnTypeRef);
} else { } else {
returnType = getBlockReturnedType(new JetScopeAdapter(scope) { returnType = getBlockReturnedType(new JetScopeAdapter(scope) {
@NotNull
@Override @Override
public Type getThisType() { public Type getThisType() {
return thisType; return receiverType;
} }
@Override @Override
@@ -92,7 +93,7 @@ public class JetTypeChecker {
} }
}, body); }, body);
} }
result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : thisType, parameterTypes, returnType); result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : receiverType, parameterTypes, returnType);
} }
@Override @Override
@@ -246,7 +247,6 @@ public class JetTypeChecker {
@Override @Override
public void visitBlockExpression(JetBlockExpression expression) { public void visitBlockExpression(JetBlockExpression expression) {
// TODO : this is a stub, consider function literals
result[0] = getBlockReturnedType(scope, expression.getStatements()); result[0] = getBlockReturnedType(scope, expression.getStatements());
} }
@@ -255,6 +255,15 @@ public class JetTypeChecker {
result[0] = JetStandardClasses.getUnitType(); result[0] = JetStandardClasses.getUnitType();
} }
@Override
public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) {
JetExpression receiverExpression = expression.getReceiverExpression();
JetExpression selectorExpression = expression.getSelectorExpression();
Type receiverType = getType(scope, receiverExpression, false);
JetScope compositeScope = new ScopeWithReceiver(scope, receiverType);
result[0] = getType(compositeScope, selectorExpression, false);
}
@Override @Override
public void visitJetElement(JetElement elem) { public void visitJetElement(JetElement elem) {
throw new IllegalArgumentException("Unsupported element: " + elem); throw new IllegalArgumentException("Unsupported element: " + elem);
@@ -264,7 +273,6 @@ public class JetTypeChecker {
} }
private Type getBlockReturnedType(@NotNull JetScope outerScope, List<JetElement> block) { private Type getBlockReturnedType(@NotNull JetScope outerScope, List<JetElement> block) {
// TODO : this is a stub, consider function literals
if (block.isEmpty()) { if (block.isEmpty()) {
return JetStandardClasses.getUnitType(); return JetStandardClasses.getUnitType();
} else { } else {
@@ -587,6 +595,11 @@ public class JetTypeChecker {
return newArguments; return newArguments;
} }
@NotNull
public Type substitute(@NotNull Type context, @NotNull Type subject) {
return substituteInType(getSubstitutionContext(context), subject);
}
private Type specializeType(Type type, List<TypeProjection> newArguments) { private Type specializeType(Type type, List<TypeProjection> newArguments) {
return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberDomain()); return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberDomain());
} }
@@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.jet.lang.modules.MemberDomain; import org.jetbrains.jet.lang.modules.MemberDomain;
import org.jetbrains.jet.lang.modules.NamespaceDomain; import org.jetbrains.jet.lang.modules.NamespaceDomain;
import java.util.Collection;
/** /**
* @author abreslav * @author abreslav
*/ */
@@ -13,7 +15,7 @@ public class NamespaceDescriptor implements NamespaceDomain, MemberDomain {
} }
@Override @Override
public MethodDescriptor getMethods(String name) { public Collection<MethodDescriptor> getMethods(String name) {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
@@ -28,6 +28,14 @@ public final class TypeImpl extends AnnotatedImpl implements Type {
this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberDomain); this(Collections.<Attribute>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberDomain);
} }
public TypeImpl(ClassDescriptor classDescriptor) {
this(Collections.<Attribute>emptyList(),
classDescriptor.getTypeConstructor(),
false,
Collections.<TypeProjection>emptyList(),
classDescriptor.getMemberDomain());
}
@Override @Override
public TypeConstructor getConstructor() { public TypeConstructor getConstructor() {
return constructor; return constructor;
@@ -3,17 +3,45 @@ package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface TypeMemberDomain { public interface TypeMemberDomain {
TypeMemberDomain EMPTY = new TypeMemberDomain() { TypeMemberDomain EMPTY = new TypeMemberDomain() {
@Override @Override
public ClassDescriptor getClassDescriptor(@NotNull Type type) { public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) {
return null;
}
@NotNull
@Override
public Collection<MethodDescriptor> getMethods(Type receiverType, String name) {
return Collections.emptyList();
}
@Override
public PropertyDescriptor getProperty(Type receiverType, String name) {
return null;
}
@Override
public ExtensionDescriptor getExtension(Type receiverType, String name) {
return null; return null;
} }
}; };
@Nullable ClassDescriptor getClassDescriptor(@NotNull Type type); @Nullable
// ... ClassDescriptor getClassDescriptor(@NotNull Type type, String name);
@NotNull
Collection<MethodDescriptor> getMethods(Type receiverType, String name);
@Nullable
PropertyDescriptor getProperty(Type receiverType, String name);
@Nullable
ExtensionDescriptor getExtension(Type receiverType, String name);
} }