public void Add(Class @class) { var typeName = new TypeName(@class.Name.Identifier); types[typeName] = new NamedType(@class); classes[typeName] = @class; }
public void CanBeConstructedFromClosedGenericClrTypes() { var closedEnumerable = new NamedType(typeof(IEnumerable<int>)); closedEnumerable.Name.ShouldEqual("System.Collections.Generic.IEnumerable"); closedEnumerable.GenericArguments.Single().ShouldEqual(new NamedType(typeof(int))); closedEnumerable.ToString().ShouldEqual("System.Collections.Generic.IEnumerable<int>"); }
public void CanBeConstructedFromNongenericClrTypes() { var intType = new NamedType(typeof(int)); intType.Name.ShouldEqual("System.Int32"); intType.GenericArguments.ShouldBeEmpty(); intType.ToString().ShouldEqual("int"); }
//TODO: Deprecated. public void Register(NamedType typeKey, params Binding[] memberBindings) { if (!typeMembers.ContainsKey(typeKey)) typeMembers[typeKey] = new List<Binding>(); var typeMemberBindings = typeMembers[typeKey]; typeMemberBindings.AddRange(memberBindings); }
private void AssertMemberType(DataType expectedType, NamedType typeKey, string memberKey) { Vector<Binding> memberBindings; if (typeMemberRegistry.TryGetMembers(typeKey, out memberBindings)) AssertMemberType(expectedType, memberBindings, memberKey); else throw new Exception("Failed to look up the type of '" + typeKey + "+" + memberKey + "' in the Scope"); }
public void CanBeConstructedFromEmptyRookClassDeclarations() { var @class = "class Foo { }".ParseClass(); var foo = new NamedType(@class); foo.Name.ShouldEqual("Foo"); foo.GenericArguments.ShouldBeEmpty(); foo.ToString().ShouldEqual("Foo"); }
public void CanBeConstructedFromClosedGenericClrTypes() { var closedEnumerable = new NamedType(typeof(IEnumerable<int>)); closedEnumerable.ShouldEqual( "System.Collections.Generic.IEnumerable", "System.Collections.Generic.IEnumerable<int>", NamedType.Integer); }
public void CanBeConstructedFromOpenGenericClrTypes() { using (TypeVariable.TestFactory()) { var openEnumerable = new NamedType(typeof(IEnumerable<>)); openEnumerable.Name.ShouldEqual("System.Collections.Generic.IEnumerable"); openEnumerable.GenericArguments.Single().ShouldEqual(new TypeVariable(0)); openEnumerable.ToString().ShouldEqual("System.Collections.Generic.IEnumerable<0>"); } }
//TODO: Just return empty collection for unknown types? Is it important to distinguish empty versus unknown? //TODO: Deprecated: instead, ask for a type by string name and generic args, then ask the resulting DataType for its members. public bool TryGetMembers(NamedType typeKey, out Vector<Binding> memberBindings) { if (typeMembers.ContainsKey(typeKey)) { memberBindings = typeMembers[typeKey].ToVector(); return true; } memberBindings = null; return false; }
public void CanCreateFullyTypedInstance() { var constructedType = new NamedType("class Foo { }".ParseClass()); var constructorType = NamedType.Constructor(constructedType); var @new = (New)Parse("new Foo()"); @new.Type.ShouldEqual(Unknown); @new.TypeName.Type.ShouldEqual(Unknown); var typedNew = WithTypes(@new, Foo => constructorType); typedNew.Type.ShouldEqual(constructedType); typedNew.TypeName.Type.ShouldEqual(constructorType); }
public void CanCreateFullyTypedInstance() { var constructedType = new NamedType("Foo"); var constructorType = NamedType.Constructor.MakeGenericType(constructedType); var @new = (New)Parse("new Foo()"); @new.Type.ShouldEqual(Unknown); @new.TypeName.Type.ShouldEqual(Unknown); var typedNew = WithTypes(@new, Foo => constructorType); typedNew.Type.ShouldEqual(constructedType); typedNew.TypeName.Type.ShouldEqual(constructorType); }
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 void CanFreshenGenericTypeVariables() { using (TypeVariable.TestFactory()) { //Prevent type '1' from being freshened by marking it as non-generic: var typeVariable0 = TypeVariable.CreateGeneric(); var typeVariable1 = TypeVariable.CreateNonGeneric(); var expectedTypeAfterLookup = new NamedType("A", new TypeVariable(2), typeVariable1, new NamedType("B", new TypeVariable(2), typeVariable1)); var definedType = new NamedType("A", typeVariable0, typeVariable1, new NamedType("B", typeVariable0, typeVariable1)); definedType.FreshenGenericTypeVariables().ShouldEqual(expectedTypeAfterLookup); } }
public void HasATypeInWhichTypeVariablesAreFreshenedOnEachScopeLookup() { using (TypeVariable.TestFactory()) { Type("foo", foo => new TypeVariable(0)).ShouldEqual(new TypeVariable(2)); } using (TypeVariable.TestFactory()) { var expectedTypeAfterLookup = new NamedType("A", new TypeVariable(2), new TypeVariable(3), new NamedType("B", new TypeVariable(2), new TypeVariable(3))); var definedType = new NamedType("A", new TypeVariable(0), new TypeVariable(1), new NamedType("B", new TypeVariable(0), new TypeVariable(1))); Type("foo", foo => definedType).ShouldEqual(expectedTypeAfterLookup); } }
public void CanBeConstructedFromRookClassDeclarationsIncludingMethods() { 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)); }); }
public void CanBeConstructedFromRookClassDeclarationsIncludingMethods() { var @class = "class Foo { int Square(int x) x*x; }".ParseClass(); var foo = new NamedType(@class); foo.Name.ShouldEqual("Foo"); foo.GenericArguments.ShouldBeEmpty(); foo.ToString().ShouldEqual("Foo"); foo.Methods.ShouldList( method => { method.Identifier.ShouldEqual("Square"); method.Type.ShouldEqual(NamedType.Function(new[] {NamedType.Integer}, NamedType.Integer)); }); }
public void LooksUpMemberBindingsForKnownClassDefinitions() { var foo = new NamedType("Foo"); var math = new NamedType("Math"); var fooBinding = "class Foo { int I() 0; bool B() true; }".ParseClass(); var mathBinding = "class Math { int Square(int x) x*x; bool Zero(int x) x==0; }".ParseClass(); typeMemberRegistry.Register(fooBinding); typeMemberRegistry.Register(mathBinding); AssertMemberType(NamedType.Function(Integer), foo, "I"); AssertMemberType(NamedType.Function(Boolean), foo, "B"); AssertMemberType(NamedType.Function(new[] { Integer }, Integer), math, "Square"); AssertMemberType(NamedType.Function(new[] { Integer }, Boolean), math, "Zero"); }
public void HasATypeInWhichOnlyGenericTypeVariablesAreFreshenedOnEachScopeLookup() { using (TypeVariable.TestFactory()) { //Prevent type '1' from being freshened on type lookup by marking it as non-generic: var typeVariable0 = TypeVariable.CreateGeneric(); var typeVariable1 = TypeVariable.CreateNonGeneric(); var expectedTypeAfterLookup = new NamedType("A", new TypeVariable(4), typeVariable1, new NamedType("B", new TypeVariable(4), typeVariable1)); var definedType = new NamedType("A", typeVariable0, typeVariable1, new NamedType("B", typeVariable0, typeVariable1)); var typeChecker = new TypeChecker(); var globalScope = new GlobalScope(); var localScope = new LocalScope(globalScope); localScope.Bind("foo", definedType); Type("foo", localScope, typeChecker).ShouldEqual(expectedTypeAfterLookup); } }
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)); }
private DataType NormalizeNamedType(NamedType named) { if (!named.IsGeneric) return named; var normalizedGenericArguments = new List<DataType>(); bool alreadyNormalized = true; foreach (var genericArgument in named.GenericArguments) { var normalizedGenericArgument = Normalize(genericArgument); if (genericArgument != normalizedGenericArgument) alreadyNormalized = false; normalizedGenericArguments.Add(normalizedGenericArgument); } if (alreadyNormalized) return named; return new NamedType(named.Name, normalizedGenericArguments.ToArray()); }
public void PerformsTypeVariableSubstitutionsAgainstNonGenericTypesByPerformingNoChanges() { var @class = "class Foo { int Square(int x) {x*x} }".ParseClass(); var foo = new NamedType(@class, new TypeRegistry()); var a = new TypeVariable(0); var replaceAWithInteger = new Dictionary<TypeVariable, DataType> { { a, NamedType.Integer } }; var fooAfterSubstitutions = (NamedType)foo.ReplaceTypeVariables(replaceAWithInteger); fooAfterSubstitutions.ShouldBeSameAs(foo); }
public void HasATypeEqualToThatOfTheTypeBeingConstructed() { var constructedType = new NamedType("Foo"); var constructorType = NamedType.Constructor.MakeGenericType(constructedType); Type("new Foo()", Foo => constructorType).ShouldEqual(constructedType); }
private DataType NormalizeNamedType(NamedType named) { return new NamedType(named.Name, named.GenericArguments.Select(Normalize).ToArray()); }
public void CanDistinguishGenericTypeDefinitionsFromSpecializations() { var intType = new NamedType(typeof(int)); var closedEnumerable = new NamedType(typeof(IEnumerable<int>)); var openEnumerable = new NamedType(typeof(IEnumerable<>)); var nonClrType = Create("A", new TypeVariable(0)); intType.IsGenericTypeDefinition.ShouldBeFalse(); closedEnumerable.IsGenericTypeDefinition.ShouldBeFalse(); openEnumerable.IsGenericTypeDefinition.ShouldBeTrue(); nonClrType.IsGenericTypeDefinition.ShouldBeFalse(); }
public void Register(Class @class) { var typeKey = new NamedType(@class.Name.Identifier); Register(typeKey, @class.Methods.Cast<Binding>().ToArray()); }
public void UsesFreshTypeVariablesUponEachConstructionFromAnOpenGenericClrType() { using (TypeVariable.TestFactory()) { var enumerableT = new NamedType(typeof(IEnumerable<>)); var enumerableS = new NamedType(typeof(IEnumerable<>)); var T = enumerableT.GenericArguments.Single(); var S = enumerableS.GenericArguments.Single(); enumerableT.ShouldNotEqual(enumerableS); T.ShouldNotEqual(S); T.ShouldEqual(new TypeVariable(0)); S.ShouldEqual(new TypeVariable(1)); } }
public void HasATypeEqualToThatOfTheTypeBeingConstructed() { var constructedType = new NamedType("class Foo { }".ParseClass()); var constructorType = NamedType.Constructor(constructedType); Type("new Foo()", Foo => constructorType).ShouldEqual(constructedType); }