Permalink
Browse files

NamedType no longer tracks a list of member Bindings. Instead, TypeRe…

…gistry can provide the list of member Bindings for any given NamedType.
  • Loading branch information...
1 parent 4eaf87b commit 28919eac0c740e3c3dde4f1b07cee7016e0d8de7 @plioi committed May 24, 2013
@@ -226,7 +226,7 @@ public Expression TypeCheck(MethodInvocation methodInvocation, Scope scope)
return methodInvocation;
}
- var typeMemberScope = new TypeMemberScope(instanceNamedType.Methods);
+ var typeMemberScope = new TypeMemberScope(typeRegistry.MembersOf(instanceNamedType));
//TODO: This block is suspiciously like Call type checking, but Callable/MethodName is evaluated in a special scope and the successful return is different.
@@ -10,10 +10,12 @@ namespace Rook.Compiling
public class TypeRegistry
{
private readonly IDictionary<TypeName, NamedType> types;
+ private readonly IDictionary<TypeName, Class> classes;
public TypeRegistry()
{
types = new Dictionary<TypeName, NamedType>();
+ classes = new Dictionary<TypeName, Class>();
RegisterCommonTypes();
}
@@ -30,7 +32,22 @@ public void Add(Class @class)
{
var typeName = new TypeName(@class.Name.Identifier);
- types[typeName] = new NamedType(@class, this);
+ types[typeName] = new NamedType(@class);
+ classes[typeName] = @class;
+ }
+
+ public Binding[] MembersOf(NamedType type)
+ {
+ var typeName = new TypeName(type.Name);
+
+ if (!classes.ContainsKey(typeName))
+ return new Binding[] { };
+
+ var @class = classes[typeName];
+
+ var result = @class.Methods.Select(m => (Binding)new MethodBinding(m.Name.Identifier, DeclaredType(m))).ToArray();
+ //TODO: Cache these results instead of recalculating each time.
+ return result;
}
public NamedType TypeOf(TypeName name)
@@ -8,7 +8,6 @@
namespace Rook.Compiling.Types
{
-
public class NamedType : DataType
{
public static readonly NamedType Void = new NamedType(typeof(Void));
@@ -57,7 +56,6 @@ private static IEnumerable<DataType> Enumerate(IEnumerable<DataType> parameterTy
private readonly Vector<DataType> genericArguments;
private readonly Lazy<string> fullName;
private readonly bool isGenericTypeDefinition;
- private readonly Binding[] methods;
[Obsolete]
public NamedType(string name, params DataType[] genericArguments)
@@ -66,22 +64,11 @@ public NamedType(string name, params DataType[] genericArguments)
this.genericArguments = genericArguments.ToVector();
isGenericTypeDefinition = false;
fullName = new Lazy<string>(GetFullName);
- methods = new Binding[] { };
}
public NamedType(Class @class)
: this(@class.Name.Identifier)
{
- if (@class.Methods.Any())
- throw new NotSupportedException("Cannot construct a NamedType from a Class that has members, unless a TypeRegistry is provided.");
-
- methods = new Binding[] {};
- }
-
- public NamedType(Class @class, TypeRegistry typeRegistry)
- : this(@class.Name.Identifier)
- {
- methods = @class.Methods.Select(m => (Binding)new MethodBinding(m.Name.Identifier, typeRegistry.DeclaredType(m))).ToArray();
}
public NamedType(Type type)
@@ -100,8 +87,6 @@ public NamedType(Type type)
: genericArguments.Select(x => (DataType)new NamedType(x)).ToVector();
fullName = new Lazy<string>(GetFullName);
-
- methods = new Binding[] { };
}
public NamedType MakeGenericType(params DataType[] typeArguments)
@@ -135,11 +120,6 @@ public override bool IsGenericTypeDefinition
get { return isGenericTypeDefinition; }
}
- public IEnumerable<Binding> Methods
- {
- get { return methods; }
- }
-
public override bool Contains(TypeVariable typeVariable)
{
return genericArguments.Any(genericArgument => genericArgument.Contains(typeVariable));
@@ -155,12 +135,6 @@ public override DataType ReplaceTypeVariables(IDictionary<TypeVariable, DataType
if (!IsGeneric)
return this;
- //TODO: Once generic types can contain methods, this will need to take special care to ensure
- // that the resulting type preserves 'this' type's methods, performing subsitutions as
- // appropriate within those methods too.
- if (Methods != null && Methods.Any())
- throw new NotImplementedException("Cannot replace type variables against generic types that have methods. The method listing is not yet preserved.");
-
return new NamedType(name, genericArguments.Select(t => t.ReplaceTypeVariables(substitutions)).ToArray());
}
@@ -34,7 +34,7 @@ public void HasATypeCorrespondingWithTheDefaultConstructor()
var fooClass = "class Foo { }".ParseClass();
var typeRegistry = new TypeRegistry();
- var constructorReturningFoo = NamedType.Constructor(new NamedType(fooClass, typeRegistry));
+ var constructorReturningFoo = NamedType.Constructor(new NamedType(fooClass));
typeRegistry.Add(fooClass);
var typeChecker = new TypeChecker(typeRegistry);
@@ -47,7 +47,7 @@ public void PassesTypeCheckingEvenWhenMethodNamesAreTheSameAsNamesInTheSurroundi
var fooClass = "class Foo { int A() {0} int B() {2} }".ParseClass();
var typeRegistry = new TypeRegistry();
- var constructorReturningFoo = NamedType.Constructor(new NamedType(fooClass, typeRegistry));
+ var constructorReturningFoo = NamedType.Constructor(new NamedType(fooClass));
typeRegistry.Add(fooClass);
var typeChecker = new TypeChecker(typeRegistry);
@@ -64,7 +64,7 @@ public void CanCreateFullyTypedInstance()
int Test() { if (Even(4)) 0 else 1 }
}".ParseClass();
- var constructorReturningFoo = NamedType.Constructor(new NamedType(@class, new TypeRegistry()));
+ var constructorReturningFoo = NamedType.Constructor(new NamedType(@class));
@class.Methods.ShouldList(
even =>
@@ -26,7 +26,7 @@ public MethodInvocationTests()
typeRegistry = new TypeRegistry();
typeRegistry.Add(mathClass);
- mathType = new NamedType(mathClass, typeRegistry);
+ mathType = new NamedType(mathClass);
}
public void DemandsMethodNameWithOptionalArguments()
@@ -127,7 +127,7 @@ public void FailsTypeCheckingForMismatchedArgumentTypes()
private DataType Type(string source, params TypeMapping[] symbols)
{
- var typeChecker = new TypeChecker();
+ var typeChecker = new TypeChecker(typeRegistry);
return Type(source, typeChecker, symbols);
}
@@ -141,7 +141,7 @@ private Vector<CompilerError> ShouldFailTypeChecking(string source, params TypeM
private T WithTypes<T>(T syntaxTree, params TypeMapping[] symbols) where T : Expression
{
- var typeChecker = new TypeChecker();
+ var typeChecker = new TypeChecker(typeRegistry);
return WithTypes(syntaxTree, typeChecker, symbols);
}
@@ -150,10 +150,5 @@ private static DataType Function(IEnumerable<DataType> parameterTypes, DataType
{
return NamedType.Function(parameterTypes, returnType);
}
-
- private static DataType Function(DataType returnType)
- {
- return Function(new DataType[] { }, returnType);
- }
}
}
@@ -32,7 +32,7 @@ public void ShouldGetTypesForRegisteredClasses()
var math = "class Math { int Square(int x) {x*x} bool Zero(int x) {x==0} }".ParseClass();
typeRegistry.Add(math);
- typeRegistry.TypeOf(new TypeName("Math")).ShouldEqual(new NamedType(math, typeRegistry));
+ typeRegistry.TypeOf(new TypeName("Math")).ShouldEqual(new NamedType(math));
}
public void ShouldGetClosedEnumerableTypesForKnownItemTypes()
@@ -94,5 +94,32 @@ public void ShouldGetDeclaredFuncTypeForFunctionDeclaration()
NamedType.Vector(NamedType.Integer),
NamedType.Boolean);
}
+
+ public void ShouldGetMemberBindingsWhenGivenTheNamedTypeOfRegisteredClasses()
+ {
+ var math = "class Math { int Square(int x) {x*x} bool Zero(int x) {x==0} int Max(int* ints) {0} }".ParseClass();
+ var mathType = new NamedType(math);
+
+ typeRegistry.Add(math);
+ var members = typeRegistry.MembersOf(mathType);
+
+ var square = members[0];
+ var zero = members[1];
+ var max = members[2];
+
+ square.Identifier.ShouldEqual("Square");
+ square.Type.ShouldEqual(NamedType.Function(new[] { NamedType.Integer }, NamedType.Integer));
+
+ zero.Identifier.ShouldEqual("Zero");
+ zero.Type.ShouldEqual(NamedType.Function(new[] { NamedType.Integer }, NamedType.Boolean));
+
+ max.Identifier.ShouldEqual("Max");
+ max.Type.ShouldEqual(NamedType.Function(new[] { NamedType.Enumerable(NamedType.Integer) }, NamedType.Integer));
+ }
+
+ public void ShouldGetNoMemberBindingsWhenGivenANamedTypeThatDoesNotCorrespondWithAnyRegisteredClass()
+ {
+ typeRegistry.MembersOf(NamedType.Integer).ShouldBeEmpty();
+ }
}
}
@@ -66,26 +66,11 @@ public void CanBeCreatedFromConvenienceFactories()
NamedType.Constructor(Create("A")).ShouldEqual(Create("Rook.Core.Constructor", Create("A")));
}
- public void CanBeConstructedFromEmptyRookClassDeclarations()
- {
- var @class = "class Foo { }".ParseClass();
-
- new NamedType(@class).ShouldEqual("Foo", "Foo");
- }
-
- public void CanBeConstructedFromRookClassDeclarationsIncludingMethods()
+ public void CanBeConstructedFromRookClassDeclarations()
{
var @class = "class Foo { int Square(int x) {x*x} }".ParseClass();
- var foo = new NamedType(@class, new TypeRegistry());
- foo.ShouldEqual("Foo", "Foo");
-
- foo.Methods.ShouldList(
- method =>
- {
- method.Identifier.ShouldEqual("Square");
- method.Type.ShouldEqual(NamedType.Function(new[] {NamedType.Integer}, NamedType.Integer));
- });
+ new NamedType(@class).ShouldEqual("Foo", "Foo");
}
public void CanBeConstructedFromNongenericClrTypes()
@@ -226,7 +211,7 @@ public void PerformsTypeVariableSubstitutionsAgainstNonGenericTypesByPerformingN
{
var @class = "class Foo { int Square(int x) {x*x} }".ParseClass();
- var foo = new NamedType(@class, new TypeRegistry());
+ var foo = new NamedType(@class);
var a = new TypeVariable(0);
var replaceAWithInteger = new Dictionary<TypeVariable, DataType> { { a, NamedType.Integer } };

0 comments on commit 28919ea

Please sign in to comment.