Ejemplo n.º 1
0
            public override IType VisitParameterizedType(ParameterizedType type)
            {
                IType newType = base.VisitParameterizedType(type);

                if (newType != type && ConstraintsValid)
                {
                    // something was changed, so we need to validate the constraints
                    ParameterizedType newParameterizedType = newType as ParameterizedType;
                    if (newParameterizedType != null)
                    {
                        // C# 4.0 spec: §4.4.4 Satisfying constraints
                        var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
                        for (int i = 0; i < typeParameters.Count; i++)
                        {
                            ITypeParameter tp      = typeParameters[i];
                            IType          typeArg = newParameterizedType.GetTypeArgument(i);
                            switch (typeArg.Kind)                               // void, null, and pointers cannot be used as type arguments
                            {
                            case TypeKind.Void:
                            case TypeKind.Null:
                            case TypeKind.Pointer:
                                ConstraintsValid = false;
                                break;
                            }
                            if (tp.HasReferenceTypeConstraint)
                            {
                                if (typeArg.IsReferenceType != true)
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasValueTypeConstraint)
                            {
                                if (!NullableType.IsNonNullableValueType(typeArg))
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasDefaultConstructorConstraint)
                            {
                                ITypeDefinition def = typeArg.GetDefinition();
                                if (def != null && def.IsAbstract)
                                {
                                    ConstraintsValid = false;
                                }
                                ConstraintsValid &= typeArg.GetConstructors(
                                    m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,
                                    GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
                                    ).Any();
                            }
                            foreach (IType constraintType in tp.DirectBaseTypes)
                            {
                                IType c = constraintType.AcceptVisitor(newParameterizedType.GetSubstitution());
                                ConstraintsValid &= conversions.IsConstraintConvertible(typeArg, c);
                            }
                        }
                    }
                }
                return(newType);
            }
Ejemplo n.º 2
0
            public override IType VisitParameterizedType(ParameterizedType type)
            {
                IType newType = base.VisitParameterizedType(type);

                if (newType != type && ConstraintsValid)
                {
                    // something was changed, so we need to validate the constraints
                    ParameterizedType newParameterizedType = newType as ParameterizedType;
                    if (newParameterizedType != null)
                    {
                        // C# 4.0 spec: §4.4.4 Satisfying constraints
                        var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
                        var substitution   = newParameterizedType.GetSubstitution();
                        for (int i = 0; i < typeParameters.Count; i++)
                        {
                            if (!ValidateConstraints(typeParameters[i], newParameterizedType.GetTypeArgument(i), substitution, conversions))
                            {
                                ConstraintsValid = false;
                                break;
                            }
                        }
                    }
                }
                return(newType);
            }
Ejemplo n.º 3
0
 AstType ConvertTypeHelper(IType type)
 {
     TypeWithElementType typeWithElementType = type as TypeWithElementType;
     if (typeWithElementType != null) {
         if (typeWithElementType is PointerType) {
             return ConvertType(typeWithElementType.ElementType).MakePointerType();
         } else if (typeWithElementType is ArrayType) {
             return ConvertType(typeWithElementType.ElementType).MakeArrayType(((ArrayType)type).Dimensions);
         } else {
             // e.g. ByReferenceType; not supported as type in C#
             return ConvertType(typeWithElementType.ElementType);
         }
     }
     ParameterizedType pt = type as ParameterizedType;
     if (pt != null) {
         if (pt.Name == "Nullable" && pt.Namespace == "System" && pt.TypeParameterCount == 1) {
             return ConvertType(pt.TypeArguments[0]).MakeNullableType();
         }
         return ConvertTypeHelper(pt.GetDefinition(), pt.TypeArguments);
     }
     ITypeDefinition typeDef = type as ITypeDefinition;
     if (typeDef != null) {
         if (typeDef.TypeParameterCount > 0) {
             // Unbound type
             IType[] typeArguments = new IType[typeDef.TypeParameterCount];
             for (int i = 0; i < typeArguments.Length; i++) {
                 typeArguments[i] = SpecialType.UnboundTypeArgument;
             }
             return ConvertTypeHelper(typeDef, typeArguments);
         } else {
             return ConvertTypeHelper(typeDef, EmptyList<IType>.Instance);
         }
     }
     return new SimpleType(type.Name);
 }
Ejemplo n.º 4
0
        protected virtual string GetCastCode(Expression expression, AstType astType, string op, out bool isCastAttr)
        {
            var resolveResult = this.Emitter.Resolver.ResolveNode(astType, this.Emitter) as TypeResolveResult;

            isCastAttr = false;

            if (resolveResult == null)
            {
                return(null);
            }

            var    exprResolveResult = this.Emitter.Resolver.ResolveNode(expression, this.Emitter);
            string inline            = null;
            bool   isOp = op == CS.Ops.IS;

            var method = isOp ? null : this.GetCastMethod(exprResolveResult.Type, resolveResult.Type, out inline);

            if (method == null && !isOp && (NullableType.IsNullable(exprResolveResult.Type) || NullableType.IsNullable(resolveResult.Type)))
            {
                method = this.GetCastMethod(NullableType.IsNullable(exprResolveResult.Type) ? NullableType.GetUnderlyingType(exprResolveResult.Type) : exprResolveResult.Type,
                                            NullableType.IsNullable(resolveResult.Type) ? NullableType.GetUnderlyingType(resolveResult.Type) : resolveResult.Type, out inline);
            }

            if (inline != null)
            {
                this.InlineMethod = method;
                return(inline);
            }

            IEnumerable <IAttribute> attributes = null;
            var type = resolveResult.Type.GetDefinition();

            if (type != null)
            {
                attributes = type.Attributes;
            }
            else
            {
                ParameterizedType paramType = resolveResult.Type as ParameterizedType;

                if (paramType != null)
                {
                    attributes = paramType.GetDefinition().Attributes;
                }
            }

            if (attributes != null)
            {
                var attribute = this.Emitter.GetAttribute(attributes, Translator.Bridge_ASSEMBLY + ".CastAttribute");

                if (attribute != null)
                {
                    isCastAttr = true;
                    return(attribute.PositionalArguments[0].ConstantValue.ToString());
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
            public override IType VisitParameterizedType(ParameterizedType type)
            {
                IType newType = base.VisitParameterizedType(type);

                if (newType != type && ConstraintsValid)
                {
                    // something was changed, so we need to validate the constraints
                    ParameterizedType newParameterizedType = newType as ParameterizedType;
                    if (newParameterizedType != null)
                    {
                        // C# 4.0 spec: §4.4.4 Satisfying constraints
                        var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
                        for (int i = 0; i < typeParameters.Count; i++)
                        {
                            ITypeParameter tp      = typeParameters[i];
                            IType          typeArg = newParameterizedType.TypeArguments[i];
                            if (tp.HasReferenceTypeConstraint)
                            {
                                if (typeArg.IsReferenceType(overloadResolution.context) != true)
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasValueTypeConstraint)
                            {
                                if (typeArg.IsReferenceType(overloadResolution.context) != false)
                                {
                                    ConstraintsValid = false;
                                }
                                if (NullableType.IsNullable(typeArg))
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasDefaultConstructorConstraint)
                            {
                                ITypeDefinition def = typeArg.GetDefinition();
                                if (def != null && def.IsAbstract)
                                {
                                    ConstraintsValid = false;
                                }
                                ConstraintsValid &= typeArg.GetConstructors(
                                    overloadResolution.context,
                                    m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public
                                    ).Any();
                            }
                            foreach (IType constraintType in tp.Constraints)
                            {
                                IType c = newParameterizedType.SubstituteInType(constraintType);
                                ConstraintsValid &= overloadResolution.IsConstraintConvertible(typeArg, c);
                            }
                        }
                    }
                }
                return(newType);
            }
Ejemplo n.º 6
0
        public AstType ConvertType(IType type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            TypeWithElementType typeWithElementType = type as TypeWithElementType;

            if (typeWithElementType != null)
            {
                if (typeWithElementType is PointerType)
                {
                    return(ConvertType(typeWithElementType.ElementType).MakePointerType());
                }
                else if (typeWithElementType is ArrayType)
                {
                    return(ConvertType(typeWithElementType.ElementType).MakeArrayType(((ArrayType)type).Dimensions));
                }
                else
                {
                    // e.g. ByReferenceType; not supported as type in C#
                    return(ConvertType(typeWithElementType.ElementType));
                }
            }
            ParameterizedType pt = type as ParameterizedType;

            if (pt != null)
            {
                if (pt.Name == "Nullable" && pt.Namespace == "System" && pt.TypeParameterCount == 1)
                {
                    return(ConvertType(pt.TypeArguments[0]).MakeNullableType());
                }
                return(ConvertTypeDefinition(pt.GetDefinition(), pt.TypeArguments));
            }
            ITypeDefinition typeDef = type as ITypeDefinition;

            if (typeDef != null)
            {
                if (typeDef.TypeParameterCount > 0)
                {
                    // Create an unbound type
                    IType[] typeArguments = new IType[typeDef.TypeParameterCount];
                    for (int i = 0; i < typeArguments.Length; i++)
                    {
                        typeArguments[i] = SharedTypes.UnknownType;
                    }
                    return(ConvertTypeDefinition(typeDef, typeArguments));
                }
                else
                {
                    return(ConvertTypeDefinition(typeDef, EmptyList <IType> .Instance));
                }
            }
            return(new SimpleType(type.Name));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Make exact inference from U to V.
        /// C# 4.0 spec: §7.5.2.8 Exact inferences
        /// </summary>
        void MakeExactInference(IType U, IType V)
        {
            Log.WriteLine("MakeExactInference from " + U + " to " + V);

            // If V is one of the unfixed Xi then U is added to the set of bounds for Xi.
            TP tp = GetTPForType(V);

            if (tp != null && tp.IsFixed == false)
            {
                Log.WriteLine(" Add exact bound '" + U + "' to " + tp);
                tp.LowerBounds.Add(U);
                tp.UpperBounds.Add(U);
                return;
            }
            // Handle by reference types:
            ByReferenceType brU = U as ByReferenceType;
            ByReferenceType brV = V as ByReferenceType;

            if (brU != null && brV != null)
            {
                MakeExactInference(brU.ElementType, brV.ElementType);
                return;
            }
            // Handle array types:
            ArrayType arrU = U as ArrayType;
            ArrayType arrV = V as ArrayType;

            if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions)
            {
                MakeExactInference(arrU.ElementType, arrV.ElementType);
                return;
            }
            // Handle parameterized type:
            ParameterizedType pU = U as ParameterizedType;
            ParameterizedType pV = V as ParameterizedType;

            if (pU != null && pV != null &&
                object.Equals(pU.GetDefinition(), pV.GetDefinition()) &&
                pU.TypeParameterCount == pV.TypeParameterCount)
            {
                Log.Indent();
                for (int i = 0; i < pU.TypeParameterCount; i++)
                {
                    MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i));
                }
                Log.Unindent();
            }
        }
Ejemplo n.º 8
0
        static bool IsIEnumerableCollectionOrList(ParameterizedType rt)
        {
            if (rt == null || rt.TypeParameterCount != 1)
            {
                return(false);
            }
            switch (rt.GetDefinition().FullName)
            {
            case "System.Collections.Generic.IList":
            case "System.Collections.Generic.ICollection":
            case "System.Collections.Generic.IEnumerable":
                return(true);

            default:
                return(false);
            }
        }
Ejemplo n.º 9
0
        static bool IsGenericInterfaceImplementedByArray(ParameterizedType rt)
        {
            if (rt == null || rt.TypeParameterCount != 1)
            {
                return(false);
            }
            switch (rt.GetDefinition().FullName)
            {
            case "System.Collections.Generic.IEnumerable":
            case "System.Collections.Generic.ICollection":
            case "System.Collections.Generic.IList":
            case "System.Collections.Generic.IReadOnlyList":
                return(true);

            default:
                return(false);
            }
        }
Ejemplo n.º 10
0
        static bool IsGenericInterfaceImplementedByArray(ParameterizedType rt)
        {
            if (rt == null || rt.TypeParameterCount != 1)
            {
                return(false);
            }
            switch (rt.GetDefinition().KnownTypeCode)
            {
            case KnownTypeCode.IEnumerableOfT:
            case KnownTypeCode.ICollectionOfT:
            case KnownTypeCode.IListOfT:
            case KnownTypeCode.IReadOnlyCollectionOfT:
            case KnownTypeCode.IReadOnlyListOfT:
                return(true);

            default:
                return(false);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Make upper bound inference from U to V.
        /// C# 4.0 spec: §7.5.2.10 Upper-bound inferences
        /// </summary>
        void MakeUpperBoundInference(IType U, IType V)
        {
            Log.WriteLine(" MakeUpperBoundInference from " + U + " to " + V);

            // If V is one of the unfixed Xi then U is added to the set of bounds for Xi.
            TP tp = GetTPForType(V);

            if (tp != null && tp.IsFixed == false)
            {
                Log.WriteLine("  Add upper bound '" + U + "' to " + tp);
                tp.UpperBounds.Add(U);
                return;
            }

            // Handle array types:
            ArrayType         arrU = U as ArrayType;
            ArrayType         arrV = V as ArrayType;
            ParameterizedType pU   = U as ParameterizedType;

            if (arrV != null && arrU != null && arrU.Dimensions == arrV.Dimensions)
            {
                MakeUpperBoundInference(arrU.ElementType, arrV.ElementType);
                return;
            }
            else if (arrV != null && IsGenericInterfaceImplementedByArray(pU) && arrV.Dimensions == 1)
            {
                MakeUpperBoundInference(pU.GetTypeArgument(0), arrV.ElementType);
                return;
            }
            // Handle parameterized types:
            if (pU != null)
            {
                ParameterizedType uniqueBaseType = null;
                foreach (IType baseV in V.GetAllBaseTypes())
                {
                    ParameterizedType pV = baseV as ParameterizedType;
                    if (pV != null && object.Equals(pU.GetDefinition(), pV.GetDefinition()) && pU.TypeParameterCount == pV.TypeParameterCount)
                    {
                        if (uniqueBaseType == null)
                        {
                            uniqueBaseType = pV;
                        }
                        else
                        {
                            return;                             // cannot make an inference because it's not unique
                        }
                    }
                }
                Log.Indent();
                if (uniqueBaseType != null)
                {
                    for (int i = 0; i < uniqueBaseType.TypeParameterCount; i++)
                    {
                        IType Ui = pU.GetTypeArgument(i);
                        IType Vi = uniqueBaseType.GetTypeArgument(i);
                        if (Ui.IsReferenceType == true)
                        {
                            // look for variance
                            ITypeParameter Xi = pU.GetDefinition().TypeParameters[i];
                            switch (Xi.Variance)
                            {
                            case VarianceModifier.Covariant:
                                MakeUpperBoundInference(Ui, Vi);
                                break;

                            case VarianceModifier.Contravariant:
                                MakeLowerBoundInference(Ui, Vi);
                                break;

                            default:                                     // invariant
                                MakeExactInference(Ui, Vi);
                                break;
                            }
                        }
                        else
                        {
                            // not known to be a reference type
                            MakeExactInference(Ui, Vi);
                        }
                    }
                }
                Log.Unindent();
            }
        }
Ejemplo n.º 12
0
        static IEnumerable <IType> ExpandIntersections(IType type)
        {
            IntersectionType it = type as IntersectionType;

            if (it != null)
            {
                return(it.Types.SelectMany(t => ExpandIntersections(t)));
            }
            ParameterizedType pt = type as ParameterizedType;

            if (pt != null)
            {
                IType[][] typeArguments = new IType[pt.TypeArguments.Count][];
                for (int i = 0; i < typeArguments.Length; i++)
                {
                    typeArguments[i] = ExpandIntersections(pt.TypeArguments[i]).ToArray();
                }
                return(AllCombinations(typeArguments).Select(ta => new ParameterizedType(pt.GetDefinition(), ta)));
            }
            return(new [] { type });
        }
Ejemplo n.º 13
0
        protected virtual string GetCastCode(Expression expression, AstType astType, out bool isInline)
        {
            var    resolveResult     = this.Emitter.Resolver.ResolveNode(astType, this.Emitter) as TypeResolveResult;
            var    exprResolveResult = this.Emitter.Resolver.ResolveNode(expression, this.Emitter);
            string inline            = null;

            isInline = false;

            var method = exprResolveResult.Type.GetMethods().FirstOrDefault(m =>
            {
                if (m.IsOperator && m.Name == "op_Explicit" &&
                    m.Parameters.Count == 1 &&
                    m.ReturnType.ReflectionName == resolveResult.Type.ReflectionName &&
                    m.Parameters[0].Type.ReflectionName == exprResolveResult.Type.ReflectionName
                    )
                {
                    string tmpInline = this.Emitter.GetInline(m);

                    if (!string.IsNullOrWhiteSpace(tmpInline))
                    {
                        inline = tmpInline;
                        return(true);
                    }
                }

                return(false);
            });

            if (inline != null)
            {
                isInline = true;
                return(inline);
            }

            if (resolveResult != null)
            {
                IEnumerable <IAttribute>      attributes = null;
                DefaultResolvedTypeDefinition type       = resolveResult.Type as DefaultResolvedTypeDefinition;

                if (type != null)
                {
                    attributes = type.Attributes;
                }
                else
                {
                    ParameterizedType paramType = resolveResult.Type as ParameterizedType;

                    if (paramType != null)
                    {
                        attributes = paramType.GetDefinition().Attributes;
                    }
                }

                if (attributes != null)
                {
                    var attribute = this.Emitter.GetAttribute(attributes, Translator.Bridge_ASSEMBLY + ".CastAttribute");

                    if (attribute != null)
                    {
                        return(attribute.PositionalArguments[0].ConstantValue.ToString());
                    }
                }
            }
            return(null);
        }