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));
 }
Exemple #3
0
 public void Resolve([NotNull] SymbolTable scope)
 {
     if (_type == null)
     {
         _type = Name.Resolve(scope);
     }
 }
Exemple #4
0
        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));
 }
Exemple #6
0
 public Symbol(string name, RType type)
 {
     Name = name;
     Type = type;
     IsClass = false;
     IsField = false;
     IsLocal = false;
 }
Exemple #7
0
 private void AddGenericParametersToScope(RType classType)
 {
     if (classType.IsGenericType)
     {
         classType.GenericParameters.ForEach(p => AddType(p.Type));
         _genericArguments = classType.GenericParameters.ToArray();
     }
 }
Exemple #8
0
        public SymbolTable(SymbolTable parent, RType classType, SymbolTable outerScope)
        {
            Parent = parent;
            _classType = classType;
            _outerSymbolTable = outerScope;

            AddGenericParametersToScope(_classType);
            AddNestedToScope(_classType);
        }
Exemple #9
0
 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);
 }
Exemple #10
0
        public RppMethodInfo MakeGenericType(RType[] genericArguments)
        {
            if (IsGenericMethod || ContainsGenericParameters)
            {
                RppInflatedMethodInfo inflatedType = new RppInflatedMethodInfo(this, genericArguments, DeclaringType);
                return inflatedType;
            }

            return this;
        }
Exemple #11
0
        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);
        }
Exemple #12
0
            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
                };
            }
Exemple #13
0
        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");
        }
Exemple #14
0
        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));
        }
Exemple #15
0
        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;
        }
Exemple #16
0
        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;
        }
Exemple #17
0
        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);
        }
Exemple #18
0
 public void TestIsInstanceOfSimpleClass()
 {
     RType fooTy = new RType("Foo", RTypeAttributes.Class, AnyTy);
     Assert.IsTrue(fooTy.IsInstanceOf(AnyTy));
     Assert.IsFalse(fooTy.IsInstanceOf(StringTy));
 }
Exemple #19
0
        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));
        }
Exemple #20
0
        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;
        }
Exemple #21
0
 public void TestAssignableFromSameType()
 {
     RType type = new RType("Foo");
     Assert.IsTrue(type.IsAssignable(type));
 }
Exemple #22
0
 private static bool IsUndefined(RType type)
 {
     return type.Name.StartsWith("Undefined");
 }
Exemple #23
0
 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;
 }
Exemple #24
0
        private static RType GetDefinitionType(RType type)
        {
            if (type.DeclaringType == null && type.IsGenericTypeDefinition)
            {
                return type;
            }

            return type.DefinitionType;
        }
Exemple #25
0
 /// <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;
 }
Exemple #26
0
        /// <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;
        }
Exemple #27
0
        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;
        }
Exemple #28
0
        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));
        }
Exemple #29
0
        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));
        }
Exemple #30
0
 public void TestSubclassOfWithBaseClass()
 {
     RType baseType = new RType("Bar");
     RType type = new RType("Foo", RTypeAttributes.Class, baseType);
     Assert.IsTrue(baseType.IsAssignable(type));
 }