Beispiel #1
0
 /// <summary> Converts the function to a matching delegate, if possible (returns null otherwise). </summary>
 /// <param name="cx">If specified, tries to find the matching delegate in this MetadataContext. If null, uses only standard delegates. </param>
 public TypeReference TryGetDelegate(MetadataContext cx = null)
 {
     // TODO: weird delegates (ref parameters, ...), many many arguments
     if (this.ResultType == TypeSignature.Void)
     {
         var reflectionAction = Type.GetType($"System.Action`{this.Params.Length}");
         if (reflectionAction is null)
         {
             return(null);
         }
         var actionSig = TypeSignature.FromType(reflectionAction);
         var actionRef = TypeReference.SpecializedType(actionSig, this.Params.Select(p => p.Type).ToImmutableArray());
         return(actionRef);
     }
     else
     {
         var reflectionAction = Type.GetType($"System.Func`{this.Params.Length + 1}");
         if (reflectionAction is null)
         {
             return(null);
         }
         var actionSig = TypeSignature.FromType(reflectionAction);
         var actionRef = TypeReference.SpecializedType(actionSig, this.Params.Select(p => p.Type).Append(this.ResultType).ToImmutableArray());
         return(actionRef);
     }
 }
Beispiel #2
0
        public static TypeDef AutoResolveImplementations(TypeDef type, MetadataContext cx)
        {
            var thisType   = type.Signature.SpecializeByItself();
            var baseTypes  = cx.GetBaseTypes(thisType).ToArray();
            var interfaces = cx.GetDirectImplements(thisType).ToArray();

            // exclude methods and properties that are already implemented
            var explicitImplMethods = new HashSet <MethodSignature>(type.Members.OfType <MethodDef>().SelectMany(m => m.Implements).Select(m => m.Signature));
            var explicitImplProps   = new HashSet <PropertySignature>(type.Members.OfType <PropertyDef>().SelectMany(m => m.Implements).Select(m => m.Signature));

            var methods    = baseTypes.Concat(interfaces).ZipSelectMany(t => cx.GetMemberMethodDefs(t.Type).Where(m => !explicitImplMethods.Contains(m))).ToLookup(m => m.Item2.Name);
            var properties = baseTypes.Concat(interfaces).ZipSelectMany(t => cx.GetMemberPropertyDefs(t.Type).Where(p => !explicitImplProps.Contains(p))).ToLookup(p => p.Item2.Name);

            var myMembers = type.Members.Select(member => {
                // implementations must be public
                if (member is MethodDef method && methods.Contains(method.Signature.Name))
                {
                    var mm = methods[method.Signature.Name]
                             .Where(m2 => m2.Item2.Params.Select(p => p.Type).SequenceEqual(method.Signature.Params.Select(p => p.Type)))
                             .Where(m2 => m2.Item2.ResultType == method.Signature.ResultType)
                             .Where(m2 => method.Signature.Accessibility == m2.Item2.Accessibility)
                             .Where(m2 => method.Signature.IsOverride || m2.Item2.DeclaringType.Kind == "interface")
                             .ToArray();
                    return(method.With(implements: method.Implements.AddRange(mm.Select(m => m.Item2.Specialize(m.Item1.TypeArguments, m.Item2.TypeParameters.Select(TypeReference.GenericParameter))))));
                }
Beispiel #3
0
        public EmitContext(E.MetadataContext metadata, EmitSettings settings, DataSchema fullSchema)
        {
            var compilation = metadata.Compilation;

            // TODO: move this assert to ExprCS
            foreach (var t in Enum.GetValues(typeof(KnownTypeCode)))
            {
                var ft = compilation.FindType((KnownTypeCode)t);
                Debug.Assert(!(ft is UnknownType) || KnownTypeCode.Unsafe.Equals(t) || t.ToString().StartsWith("IAsync"));
            }

            Metadata    = metadata;
            Compilation = compilation;
            Module      = Compilation.MainModule;
            Settings    = settings;
            FullSchema  = fullSchema;
        }
Beispiel #4
0
        public static TypeDef Fix(TypeDef type, MetadataContext cx)
        {
            // note that none of the referenced types must be defined in `cx`. This function is called before the types are committed.

            var kind = type.Signature.Kind;

            if (kind == "class" && !(type.Signature.IsAbstract && !type.Signature.CanOverride) && !type.Members.OfType <MethodDef>().Any(m => m.Signature.IsConstructor()))
            {
                type = type.AddMember(
                    MethodDef.Create(MethodSignature.ImplicitConstructor(type.Signature), @this => @this.Read().Box().CallMethod(MethodSignature.Object_Constructor))
                    );
            }

            // apply to descendant types
            type = type.With(members: type.Members.EagerSelect(m => m is TypeDef t ? Fix(t, cx) : m));

            return(type);
        }
Beispiel #5
0
        // public static TS.ITypeDefinition GetTypeDefinition(this MetadataContext c, TypeSignature t) =>
        //     (TS.ITypeDefinition)c.DeclaredEntities.GetValueOrDefault(t) ??
        //     c.Compilation.FindType(t.GetFullTypeName()).GetDefinition() ??
        //     throw new Exception($"Could not resolve {t.GetFullTypeName()} for some reason.");


        public static TS.IType GetTypeReference(this MetadataContext c, TypeReference tref) =>
        tref.Match(
            st => {
            if (st.TypeArguments.IsEmpty)
            {
                return((IType)c.GetTypeDef(st.Type));
            }
            var genericType =
                // when we have a parent type, we first need specialize it, then we can specialize our type
                // st.DeclaringType() is SpecializedType declaringType ?
                // c.GetTypeReference(declaringType).GetNestedTypes(t => t.Name == st.Type.Name && t.TypeParameterCount == st.Type.TypeParameters.Length).Single() :
                c.GetTypeDef(st.Type);

            return(new ParameterizedType(
                       genericType,
                       st.TypeArguments
                       //   .Skip(st.GenericParameters.Length - st.Type.TypeParameters.Length)
                       .Select(p => GetTypeReference(c, p))));
        },
            arrayType => new TS.ArrayType(c.Compilation, GetTypeReference(c, arrayType.Type), arrayType.Dimensions),
            byrefType => new TS.ByReferenceType(GetTypeReference(c, byrefType.Type)),
            pointerType => new TS.PointerType(GetTypeReference(c, pointerType.Type)),
            gParam => c.GenericParameterStore.Retreive(gParam),
            function => throw new NotSupportedException($"Function types are not supported in metadata")
Beispiel #6
0
 /// <summary>
 /// Gets the invoke method for a delegate type.
 /// </summary>
 /// <remarks>
 /// Returns null if the type is not a delegate type; or if the invoke method could not be found.
 /// </remarks>
 public static MethodReference GetDelegateInvokeMethod(this SpecializedType @delegate, MetadataContext cx)
 {
     if (@delegate == null)
     {
         throw new ArgumentNullException("type");
     }
     if (@delegate.Type.Kind == "delegate")
     {
         return(cx.GetMemberMethods(@delegate).FirstOrDefault(m => m.Name() == "Invoke"));
     }
     else
     {
         return(null);
     }
 }
Beispiel #7
0
        /// <summary> Returns the element type of any class implementing <see cref="IEnumerable{T}" /> interface. Returns null when it is not found. </summary>
        public static TypeReference GetElementTypeFromIEnumerable(this SpecializedType collectionType, MetadataContext cx, bool allowIEnumerator, out bool?isGeneric)
        {
            bool foundNonGenericIEnumerable = false;

            foreach (var baseType in cx.GetBaseTypes(collectionType))
            {
                if (baseType.Type == TypeSignature.IEnumerableOfT || (allowIEnumerator && baseType.Type == TypeSignature.IEnumeratorOfT))
                {
                    isGeneric = true;
                    return(Assert.Single(baseType.TypeArguments));
                }
                if (baseType.Type == TypeSignature.IEnumerable || (allowIEnumerator && baseType.Type == TypeSignature.IEnumerator))
                {
                    foundNonGenericIEnumerable = true;
                }
            }
            // System.Collections.IEnumerable found in type hierarchy -> Object is element type.
            if (foundNonGenericIEnumerable)
            {
                isGeneric = false;
                return(TypeSignature.Object);
            }
            isGeneric = null;
            return(null);
        }
Beispiel #8
0
        /// <summary> Returns the element type of any class implementing <see cref="IEnumerable{T}" /> interface. Returns null when it is not found. </summary>
        public static TypeReference GetElementTypeFromIEnumerable(this TypeReference collectionType, MetadataContext cx, bool allowIEnumerator, out bool?isGeneric)
        {
            bool?isGeneric_ = null;
            var  r          = collectionType.Match(
                st => GetElementTypeFromIEnumerable(st, cx, allowIEnumerator, out isGeneric_),
                arr => {
                if (arr.Dimensions == 1)
                {
                    isGeneric_ = true;
                    return(arr.Type);
                }
                else
                {
                    return(null);
                }
            },
                _ => null,
                _ => null,
                _ => null,
                _ => null);

            isGeneric = isGeneric_;
            return(r);
        }
Beispiel #9
0
 /// <summary>
 /// Gets whether this type definition is derived from the base type definition.
 /// </summary>
 public static bool IsDerivedFrom(this SpecializedType type, SpecializedType baseType, MetadataContext cx)
 {
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     if (baseType == null)
     {
         return(false);
     }
     return(cx.GetBaseTypes(type).Contains(baseType));
 }
Beispiel #10
0
        /// <summary>
        /// Converts a delegate to a matching function type.
        /// </summary>
        /// <remarks>
        /// Returns null if the type is not a delegate type; or if the invoke method could not be found.
        /// </remarks>
        public static FunctionType DelegateToFunction(this SpecializedType @delegate, MetadataContext cx)
        {
            var invoke = @delegate.GetDelegateInvokeMethod(cx);

            return(invoke?.ToFunctionType());
        }