public void TestAssignableFromSameType2() { RType type1 = new RType("Foo"); RType type2 = new RType("Foo"); Assert.IsFalse(type1.IsAssignable(type2)); // Same types should point to the same type object Assert.IsTrue(type1.IsAssignable(type1)); }
public void TestSubclassOfWithInterface() { RType iBarTy = new RType("IBar", RTypeAttributes.Interface); RType fooTy = new RType("Foo"); fooTy.AddInterfaceImplementation(iBarTy); Assert.IsTrue(iBarTy.IsAssignable(fooTy)); }
public void Resolve([NotNull] SymbolTable scope) { if (_type == null) { _type = Name.Resolve(scope); } }
private RppMethodInfo FindGenericConstructor(RType targetType, out RType inferredType) { inferredType = null; IReadOnlyList<RppMethodInfo> constructors = targetType.Constructors; foreach (RppMethodInfo constructor in constructors) { if (NeedToInferGenericArguments(targetType)) { var genericParameters = targetType.GenericParameters; List<RType> argTypes = ArgsTypes.ToList(); var inferredTypeArguments = InferGenericArguments(genericParameters, argTypes, constructor.Parameters.Select(p => p.Type)); if (inferredTypeArguments.Any(t => t.IsUndefined())) { continue; } RType inflatedType = targetType.MakeGenericType(inferredTypeArguments); var matchingConstructors = FindConstructors(inflatedType); if (matchingConstructors.Count > 1) { throw SemanticExceptionFactory.AmbiguousReferenceToOverloadedDefinition(Token, matchingConstructors, argTypes); } if (matchingConstructors.Count == 1) { inferredType = inflatedType; return matchingConstructors.First(); } } } throw SemanticExceptionFactory.SomethingWentWrong(Token); }
public void TestSubclassOfWithBaseBaseClass() { RType barTy = new RType("Bar"); RType zooTy = new RType("Zoo", RTypeAttributes.Class, barTy); RType fooTy = new RType("Foo", RTypeAttributes.Class, zooTy); Assert.IsTrue(barTy.IsAssignable(fooTy)); }
public Symbol(string name, RType type) { Name = name; Type = type; IsClass = false; IsField = false; IsLocal = false; }
private void AddGenericParametersToScope(RType classType) { if (classType.IsGenericType) { classType.GenericParameters.ForEach(p => AddType(p.Type)); _genericArguments = classType.GenericParameters.ToArray(); } }
public SymbolTable(SymbolTable parent, RType classType, SymbolTable outerScope) { Parent = parent; _classType = classType; _outerSymbolTable = outerScope; AddGenericParametersToScope(_classType); AddNestedToScope(_classType); }
public void TypeDefinitionForClass() { var t = new RType("Foo", RTypeAttributes.Class); Assert.IsTrue(t.IsClass); Assert.IsFalse(t.IsAbstract); Assert.IsFalse(t.IsArray); Assert.IsFalse(t.IsGenericType); Assert.IsFalse(t.IsPrimitive); Assert.IsFalse(t.IsSealed); }
public RppMethodInfo MakeGenericType(RType[] genericArguments) { if (IsGenericMethod || ContainsGenericParameters) { RppInflatedMethodInfo inflatedType = new RppInflatedMethodInfo(this, genericArguments, DeclaringType); return inflatedType; } return this; }
public override IEnumerable<IRppExpr> DeclareVariables(RType inputType) { if (Name == "_") { return Collections.NoExprs; } RppVar variable = Val(Name, inputType, new RppDefaultExpr(inputType.AsResolvable())); variable.Token = Token; return List(variable); }
public virtual IRppExpr RewriteFunctionCall(RType targetType, string functionName, IList<IRppExpr> resolvedArgList, IList<RType> typeArgs) { List<ResolvableType> resolvableTypeArgs = ConvertToResolvableType(GetTypeArguments(typeArgs)).ToList(); RType returnType = GetReturnType(typeArgs); return new RppFuncCall(functionName, resolvedArgList, Method, new ResolvableType(returnType), resolvableTypeArgs) { TargetType = targetType, IsFromClosure = _isInsideClosure }; }
public static IRppExpr CastIfNeeded(IRppExpr sourceExpr, RType targetType) { RType sourceType = sourceExpr.Type.Value; if (sourceType.Equals(targetType)) { return sourceExpr; } if (sourceType.IsPrimitive && targetType == RppTypeSystem.AnyTy) { return new RppBox(sourceExpr); } /* if (sourceType.IsValueType && targetType == typeof (object)) { return new RppBox(sourceExpr); } if (IsAssignable(sourceExpr.Type.Runtime, targetType)) { return sourceExpr; } if (sourceExpr.Type.Runtime.IsSubclassOf(targetType)) { return sourceExpr; } */ if (sourceType.IsSubclassOf(targetType)) { return sourceExpr; } if (targetType.IsClass && sourceType == RppTypeSystem.NullTy) { return sourceExpr; } if (sourceType == RppTypeSystem.NothingTy) { return sourceExpr; } throw new Exception("Can't cast expression to a specific type"); }
public void TestSpecializedGenericTypesEquality() { // class Foo[T](val id: T) // class SecondFoo[A](id: Int, val name: A) extends Foo[Int](id) RType fooTy = new RType("Foo"); fooTy.DefineGenericParameters("T"); RType intFooTy = fooTy.MakeGenericType(IntTy); RType secondTy = new RType("SecondFoo"); secondTy.DefineGenericParameters("A"); secondTy.BaseType = intFooTy; Assert.IsTrue(secondTy.IsGenericType); Assert.IsTrue(secondTy.IsGenericTypeDefinition); Assert.IsTrue(intFooTy.IsAssignable(secondTy)); }
public RInflatedType([NotNull] RType type, RType[] genericArguments) : base(type.Name, type.Attributes, null, type.DeclaringType) { BaseType = InflateBaseType(type.BaseType, genericArguments); DefinitionType = type; IsArray = type.IsArray; if (!type.IsGenericType) { throw new Exception("Can't inflate non generic type"); } if (type.GenericParameters.Count != genericArguments.Length) { throw new Exception("There are different amount of generic arguments and parameters, they should be the same"); } _genericArguments = genericArguments; }
public static bool CanCast(RType source, RType dest) { if (source.IsPrimitive && Equals(dest, RppTypeSystem.AnyTy)) { return true; } if ((dest.IsClass || dest.IsGenericParameter) && Equals(source, RppTypeSystem.NullTy)) { return true; } if (dest.IsAssignable(source)) { return true; } if (Equals(source, RppTypeSystem.NothingTy)) { return true; } return false; }
public void FindCommonType() { RType fooTy = new RType("Foo"); RType barTy = new RType("Bar"); RType commonTy = TypeInference.ResolveCommonType(fooTy, barTy); Assert.IsNotNull(commonTy); Assert.AreEqual(AnyTy, commonTy); }
public void TestIsInstanceOfSimpleClass() { RType fooTy = new RType("Foo", RTypeAttributes.Class, AnyTy); Assert.IsTrue(fooTy.IsInstanceOf(AnyTy)); Assert.IsFalse(fooTy.IsInstanceOf(StringTy)); }
public void TestIsInstanceOfClassWhichImplementsInterface() { RType interfaceTy = new RType("IBar", RTypeAttributes.Interface); RType fooTy = new RType("Foo"); fooTy.AddInterfaceImplementation(interfaceTy); Assert.IsTrue(fooTy.IsInstanceOf(interfaceTy)); RType anotherInterfaceTy = new RType("IBar", RTypeAttributes.Interface); Assert.IsTrue(fooTy.IsInstanceOf(anotherInterfaceTy)); RType wrongInterfaceTy = new RType("IFoo", RTypeAttributes.Interface); Assert.IsFalse(fooTy.IsInstanceOf(wrongInterfaceTy)); }
protected override bool IsCovariant(RType right) { RInflatedType other = right as RInflatedType; if (other == null) { return false; } if (IsConstructedGenericType && right.IsConstructedGenericType && ReferenceEquals(DefinitionType, other.DefinitionType)) { RppGenericParameter[] genericParameters = DefinitionType.GenericParameters.ToArray(); RType[] otherGenericArguments = other.GenericArguments.ToArray(); for (int i = 0; i < genericParameters.Length; i++) { RppGenericParameter p = genericParameters[i]; RType type = _genericArguments[i]; RType otherType = otherGenericArguments[i]; if (type.IsPrimitive != otherType.IsPrimitive) { return false; } switch (p.Variance) { case RppGenericParameterVariance.Invariant: if (type != otherType) { return false; } break; case RppGenericParameterVariance.Covariant: if (!type.IsAssignable(otherType)) { return false; } break; case RppGenericParameterVariance.Contravariant: if (!otherType.IsAssignable(type)) { return false; } break; default: throw new ArgumentOutOfRangeException(); } } return true; } return false; }
public void TestAssignableFromSameType() { RType type = new RType("Foo"); Assert.IsTrue(type.IsAssignable(type)); }
private static bool IsUndefined(RType type) { return type.Name.StartsWith("Undefined"); }
private static RType CreateArrayType() { RType arrayType = new RType("Array") {IsArray = true}; RppGenericParameter genericParameter = arrayType.DefineGenericParameters("A")[0]; arrayType.DefineConstructor(RMethodAttributes.Public, new[] {new RppParameterInfo("size", IntTy)}); arrayType.DefineMethod("length", RMethodAttributes.Public, IntTy, new RppParameterInfo[0]); arrayType.DefineMethod("apply", RMethodAttributes.Public, genericParameter.Type, new[] {new RppParameterInfo("index", IntTy)}, new RppGenericParameter[0]); arrayType.DefineMethod("update", RMethodAttributes.Public, UnitTy, new[] {new RppParameterInfo("index", IntTy), new RppParameterInfo("value", genericParameter.Type)}, new RppGenericParameter[0]); return arrayType; }
private static RType GetDefinitionType(RType type) { if (type.DeclaringType == null && type.IsGenericTypeDefinition) { return type; } return type.DefinitionType; }
/// <summary> /// Checks if 2 types are different by comparing names but also it checks if type was defined as method's generics /// because generics can be defined for classes and methods, clr distinguishes them with "!!" and "!". /// </summary> /// <param name="source">first type</param> /// <param name="target">second type</param> /// <returns><code>true</code> if different</returns> private static bool AreDifferent(RType source, RType target) { return target.Name != source.Name || !ReferenceEquals(source, target) || target.IsMethodGenericParameter != source.IsMethodGenericParameter; }
/// <summary> /// Returns generic arguments of specified type or if they are not specified, returns /// all generic arguments "Undefined". /// </summary> /// <param name="type">specified type</param> /// <returns>generic arguments of type or "Undefined" types which match amount of generic parameters</returns> private static IEnumerable<RType> GetGenericArguments(RType type) { if (type.GenericArguments.Count == 0) { return Enumerable.Range(0, type.GenericParameters.Count).Select(x => Undefined); } return type.GenericArguments; }
private static RType Infer(RType source, RType target, IDictionary<int, RType> dict) { RType finalType; if (target.IsGenericParameter && dict.TryGetValue(target.GenericParameterPosition, out finalType)) { return finalType; } if (IsUndefined(source)) { return target; } if (target.IsGenericParameter && !dict.ContainsKey(target.GenericParameterPosition) && AreDifferent(source, target)) { dict.Add(target.GenericParameterPosition, source); return source; } if (source.IsGenericType) { var newGenericArguments = GetGenericArguments(source).Zip(target.GenericArguments, (left, right) => Infer(left, right, dict)) .ToArray(); // Add generic arguments to dictionary in case they were resolved to some real type for (int i = 0; i < newGenericArguments.Length; i++) { if (!newGenericArguments[i].IsGenericParameter && !dict.ContainsKey(i)) { dict.Add(i, newGenericArguments[i]); } } if (source == target) return target; return GetDefinitionType(source).MakeGenericType(newGenericArguments); } return source; }
public void TestOneGenericContainerWith2DistinctClasses() { // class List[A] // class Apple // class Orange // listOfApples = new List[Apple]() // listOfOranges = new List[Orange]() RType listTy = new RType("List"); listTy.DefineGenericParameters("A"); RType appleTy = new RType("Apple"); RType listOfApplesTy = listTy.MakeGenericType(appleTy); RType orangeTy = new RType("Orange"); RType listOfOrangesTy = listTy.MakeGenericType(orangeTy); Assert.IsFalse(listOfOrangesTy.IsAssignable(listOfApplesTy)); Assert.IsFalse(listOfApplesTy.IsAssignable(listOfOrangesTy)); Assert.IsTrue(listOfOrangesTy.IsAssignable(listOfOrangesTy)); }
public void TestAssigningNothing() { RType optionTy = new RType("Option"); RppGenericParameter[] genericParameters = optionTy.DefineGenericParameters("A"); genericParameters[0].Variance = RppGenericParameterVariance.Covariant; RType nothingOptionTy = optionTy.MakeGenericType(NothingTy); RType stringOptionTy = optionTy.MakeGenericType(StringTy); Assert.IsTrue(stringOptionTy.IsAssignable(nothingOptionTy)); }
public void TestSubclassOfWithBaseClass() { RType baseType = new RType("Bar"); RType type = new RType("Foo", RTypeAttributes.Class, baseType); Assert.IsTrue(baseType.IsAssignable(type)); }