diff --git a/idea/src/org/jetbrains/jet/lang/modules/MemberDomain.java b/idea/src/org/jetbrains/jet/lang/modules/MemberDomain.java index c6172cb7be4..14182a867a3 100644 --- a/idea/src/org/jetbrains/jet/lang/modules/MemberDomain.java +++ b/idea/src/org/jetbrains/jet/lang/modules/MemberDomain.java @@ -1,17 +1,20 @@ 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 { - @Nullable - MethodDescriptor getMethods(String name); + @NotNull + Collection getMethods(String name); @Nullable ClassDescriptor getClass(String name); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 4e613ed1e6c..e6bf519b2a7 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -18,27 +18,84 @@ public class ClassDescriptorResolver { @Nullable 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 typeParameters - = resolveTypeParameters(extensibleScope, classElement.getTypeParameters()); + = resolveTypeParameters(typeParameterScope, classElement.getTypeParameters()); List delegationSpecifiers = classElement.getDelegationSpecifiers(); + // TODO : assuming that the hierarchy is acyclic Collection superclasses = delegationSpecifiers.isEmpty() ? Collections.singleton(JetStandardClasses.getAnyType()) - : resolveTypes(extensibleScope, delegationSpecifiers); - boolean open = classElement.getModifierList().hasModifier(JetTokens.OPEN_KEYWORD); + : resolveTypes(typeParameterScope, delegationSpecifiers); + boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); return new ClassDescriptor( AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()), !open, classElement.getName(), typeParameters, - superclasses + superclasses, + resolveMemberDomain(classElement, scope, typeParameterScope, superclasses) ); } + private TypeMemberDomain resolveMemberDomain( + final JetClass classElement, + final JetScope outerScope, + final TypeParameterExtensibleScope typeParameterScope, + final Collection supertypes) { + // TODO : Cache!!! + return new TypeMemberDomain() { + @Override + public PropertyDescriptor getProperty(Type receiverType, @NotNull String name) { + // TODO : primary constructor parameters + List 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 getMethods(Type receiverType, String name) { + throw new UnsupportedOperationException(); // TODO + } + + @Override + public ExtensionDescriptor getExtension(Type receiverType, String name) { + throw new UnsupportedOperationException(); // TODO + } + }; + } + private static List resolveTypeParameters(TypeParameterExtensibleScope extensibleScope, List typeParameters) { + // TODO : When-clause List result = new ArrayList(); for (JetTypeParameter typeParameter : typeParameters) { result.add(resolveTypeParameter(extensibleScope, typeParameter)); @@ -76,31 +133,6 @@ public class ClassDescriptorResolver { return TypeResolver.INSTANCE.resolveType(scope, typeReference); } - private static final class TypeParameterExtensibleScope extends JetScopeAdapter { - - private final Map typeParameterDescriptors = new HashMap(); - 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 public PropertyDescriptor resolvePropertyDescriptor(@NotNull JetScope scope, @NotNull JetParameter parameter) { return new PropertyDescriptor( @@ -128,4 +160,30 @@ public class ClassDescriptorResolver { property.getName(), type); } + + private static final class TypeParameterExtensibleScope extends JetScopeAdapter { + + private final Map typeParameterDescriptors = new HashMap(); + 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); + } + + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java index 6de917a542e..af741e9450f 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeAdapter.java @@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; +import java.util.Collection; + /** * @author abreslav */ @@ -30,7 +32,7 @@ public class JetScopeAdapter implements JetScope { } @Override - public MethodDescriptor getMethods(String name) { + public Collection getMethods(String name) { return scope.getMethods(name); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java index 72dc863ab8b..cfd9db66d01 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/JetScopeImpl.java @@ -1,14 +1,19 @@ package org.jetbrains.jet.lang.resolve; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.types.*; +import java.util.Collection; +import java.util.Collections; + /** * @author abreslav */ public abstract class JetScopeImpl implements JetScope { @Override - public MethodDescriptor getMethods(String name) { - return null; + @NotNull + public Collection getMethods(String name) { + return Collections.emptyList(); } @Override @@ -36,6 +41,7 @@ public abstract class JetScopeImpl implements JetScope { return null; } + @NotNull @Override public Type getThisType() { return JetStandardClasses.getNothingType(); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java new file mode 100644 index 00000000000..5f014ffb3a7 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithReceiver.java @@ -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 getMethods(String name) { + return receiverTypeScope.getMethods(name); + // TODO : Extension methods +// Collection 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(); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 07dd6c642f5..49a21cbcd2f 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -2,7 +2,6 @@ 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.psi.*; import org.jetbrains.jet.lang.types.*; @@ -162,15 +161,16 @@ public class TypeResolver { if (qualifier != null) { // 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? - MemberDomain domain = resolveClass(scope, qualifier); - if (domain == null) { - domain = resolveNamespace(scope, qualifier); - } - - if (domain != null) { - return domain.getClass(expression.getReferencedName()); - } - return null; + throw new UnsupportedOperationException(); +// MemberDomain domain = resolveClass(scope, qualifier); +// if (domain == null) { +// domain = resolveNamespace(scope, qualifier); +// } +// +// if (domain != null) { +// return domain.getClass(expression.getReferencedName()); +// } +// return null; } assert qualifier == null; diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeScope.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeScope.java new file mode 100644 index 00000000000..e1830370c48 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeScope.java @@ -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 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; + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java index 33817545fac..075db373af7 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptor.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.modules.MemberDomain; import java.util.Collection; import java.util.Collections; @@ -10,20 +9,23 @@ import java.util.List; /** * @author abreslav */ -public class ClassDescriptor extends MemberDescriptorImpl implements MemberDomain { +public class ClassDescriptor extends MemberDescriptorImpl { private final TypeConstructor typeConstructor; + private final TypeMemberDomain memberDomain; public ClassDescriptor( List attributes, boolean sealed, - String name, List typeParameters, Collection superclasses) { + String name, List typeParameters, + Collection superclasses, TypeMemberDomain memberDomain) { super(attributes, name); this.typeConstructor = new TypeConstructor(attributes, sealed, name, typeParameters, superclasses); + this.memberDomain = memberDomain; } - public ClassDescriptor(String name) { + public ClassDescriptor(String name, TypeMemberDomain memberDomain) { this(Collections.emptyList(), true, name, Collections.emptyList(), - Collections.singleton(JetStandardClasses.getAnyType())); + Collections.singleton(JetStandardClasses.getAnyType()), memberDomain); } @NotNull @@ -31,22 +33,12 @@ public class ClassDescriptor extends MemberDescriptorImpl implements MemberDomai return typeConstructor; } + public TypeMemberDomain getMemberDomain() { + return memberDomain; + } + public ClassDescriptor getClass(String referencedName) { 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 - } -} +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index ce5490505d4..776008bba3d 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.Collections; /** @@ -10,7 +11,23 @@ import java.util.Collections; public class ErrorType { private static final TypeMemberDomain ERROR_DOMAIN = new TypeMemberDomain() { @Override - public ClassDescriptor getClassDescriptor(@NotNull Type type) { + public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) { + throw new UnsupportedOperationException(); // TODO + } + + @NotNull + @Override + public Collection 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 } }; diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 92ecc7aaeef..d99ff99216b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -34,7 +34,7 @@ public class JetStandardClasses { public int size() { throw new UnsupportedOperationException(); } - } + }, TypeMemberDomain.EMPTY ); private static final ClassDescriptor ANY = new ClassDescriptor( @@ -42,24 +42,50 @@ public class JetStandardClasses { false, "Any", Collections.emptyList(), - Collections.emptySet() + Collections.emptySet(), + TypeMemberDomain.EMPTY ); - private static final Type ANY_TYPE = new TypeImpl(ANY.getTypeConstructor(), TypeMemberDomain.EMPTY); - private static final Type NULLABLE_ANY_TYPE = TypeUtils.makeNullable(ANY_TYPE); + public static final TypeMemberDomain STUB = new TypeMemberDomain() { + @Override + public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) { + throw new UnsupportedOperationException(); // TODO + } - private static final ClassDescriptor BYTE = new ClassDescriptor("Byte"); - private static final ClassDescriptor CHAR = new ClassDescriptor("Char"); - private static final ClassDescriptor SHORT = new ClassDescriptor("Short"); - private static final ClassDescriptor INT = new ClassDescriptor("Int"); - private static final ClassDescriptor LONG = new ClassDescriptor("Long"); - private static final ClassDescriptor FLOAT = new ClassDescriptor("Float"); - private static final ClassDescriptor DOUBLE = new ClassDescriptor("Double"); - private static final ClassDescriptor BOOLEAN = new ClassDescriptor("Boolean"); - private static final ClassDescriptor STRING = new ClassDescriptor("String"); + @NotNull + @Override + public Collection 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 + } + }; + + 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; private static final ClassDescriptor[] TUPLE = new ClassDescriptor[TUPLE_COUNT]; + static { for (int i = 0; i < TUPLE_COUNT; i++) { List parameters = new ArrayList(); @@ -74,13 +100,14 @@ public class JetStandardClasses { true, "Tuple" + i, parameters, - Collections.singleton(JetStandardClasses.getAnyType())); + Collections.singleton(JetStandardClasses.getAnyType()), STUB); } } - public static final int FUNCTION_COUNT = 22; private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; + + static { for (int i = 0; i < FUNCTION_COUNT; i++) { List parameters = new ArrayList(); @@ -99,7 +126,7 @@ public class JetStandardClasses { false, "Function" + i, parameters, - Collections.singleton(JetStandardClasses.getAnyType())); + Collections.singleton(JetStandardClasses.getAnyType()), STUB); parameters.add(0, new TypeParameterDescriptor( Collections.emptyList(), Variance.IN_VARIANCE, "T", @@ -109,29 +136,22 @@ public class JetStandardClasses { false, "ReceiverFunction" + i, 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( Collections.emptyList(), getNothing().getTypeConstructor(), diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 5365bd98530..844e61e94a2 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -53,11 +53,11 @@ public class JetTypeChecker { JetTypeReference returnTypeRef = expression.getReturnTypeRef(); JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); - final Type thisType; + final Type receiverType; if (receiverTypeRef != null) { - thisType = TypeResolver.INSTANCE.resolveType(scope, receiverTypeRef); + receiverType = TypeResolver.INSTANCE.resolveType(scope, receiverTypeRef); } else { - thisType = scope.getThisType(); + receiverType = scope.getThisType(); } List body = expression.getBody(); @@ -77,9 +77,10 @@ public class JetTypeChecker { returnType = TypeResolver.INSTANCE.resolveType(scope, returnTypeRef); } else { returnType = getBlockReturnedType(new JetScopeAdapter(scope) { + @NotNull @Override public Type getThisType() { - return thisType; + return receiverType; } @Override @@ -92,7 +93,7 @@ public class JetTypeChecker { } }, body); } - result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : thisType, parameterTypes, returnType); + result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : receiverType, parameterTypes, returnType); } @Override @@ -246,7 +247,6 @@ public class JetTypeChecker { @Override public void visitBlockExpression(JetBlockExpression expression) { - // TODO : this is a stub, consider function literals result[0] = getBlockReturnedType(scope, expression.getStatements()); } @@ -255,6 +255,15 @@ public class JetTypeChecker { 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 public void visitJetElement(JetElement elem) { throw new IllegalArgumentException("Unsupported element: " + elem); @@ -264,7 +273,6 @@ public class JetTypeChecker { } private Type getBlockReturnedType(@NotNull JetScope outerScope, List block) { - // TODO : this is a stub, consider function literals if (block.isEmpty()) { return JetStandardClasses.getUnitType(); } else { @@ -587,6 +595,11 @@ public class JetTypeChecker { return newArguments; } + @NotNull + public Type substitute(@NotNull Type context, @NotNull Type subject) { + return substituteInType(getSubstitutionContext(context), subject); + } + private Type specializeType(Type type, List newArguments) { return new TypeImpl(type.getAttributes(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberDomain()); } diff --git a/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java index f625adc153b..d95c984cf1b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/NamespaceDescriptor.java @@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.jet.lang.modules.MemberDomain; import org.jetbrains.jet.lang.modules.NamespaceDomain; +import java.util.Collection; + /** * @author abreslav */ @@ -13,7 +15,7 @@ public class NamespaceDescriptor implements NamespaceDomain, MemberDomain { } @Override - public MethodDescriptor getMethods(String name) { + public Collection getMethods(String name) { throw new UnsupportedOperationException(); // TODO } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeImpl.java b/idea/src/org/jetbrains/jet/lang/types/TypeImpl.java index b42085ef809..d44ad6a1f78 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeImpl.java @@ -28,6 +28,14 @@ public final class TypeImpl extends AnnotatedImpl implements Type { this(Collections.emptyList(), constructor, false, Collections.emptyList(), memberDomain); } + public TypeImpl(ClassDescriptor classDescriptor) { + this(Collections.emptyList(), + classDescriptor.getTypeConstructor(), + false, + Collections.emptyList(), + classDescriptor.getMemberDomain()); + } + @Override public TypeConstructor getConstructor() { return constructor; diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeMemberDomain.java b/idea/src/org/jetbrains/jet/lang/types/TypeMemberDomain.java index a1db793c0f1..25a95bd0f05 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeMemberDomain.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeMemberDomain.java @@ -3,17 +3,45 @@ 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 type) { + public ClassDescriptor getClassDescriptor(@NotNull Type type, String name) { + return null; + } + + @NotNull + @Override + public Collection 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; } }; - @Nullable ClassDescriptor getClassDescriptor(@NotNull Type type); - // ... + @Nullable + ClassDescriptor getClassDescriptor(@NotNull Type type, String name); + + @NotNull + Collection getMethods(Type receiverType, String name); + + @Nullable + PropertyDescriptor getProperty(Type receiverType, String name); + + @Nullable + ExtensionDescriptor getExtension(Type receiverType, String name); }