Beispiel #1
0
        public TypeInfo GetTypeInformation(TypeReference type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            TypeInfo result;
            var      typedef = TypeUtil.GetTypeDefinition(type);

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

            var identifier = new TypeIdentifier(typedef);

            if (TypeInformation.TryGet(identifier, out result))
            {
                return(result);
            }

            var args = new MakeTypeInfoArgs();

            EnqueueType(args.TypesToInitialize, type);

            // We must construct type information in two passes, so that method group construction
            //  behaves correctly and ignores all the right methods.
            // The first pass walks all the way through the type graph (starting with the current type),
            //  ensuring we have type information for all the types in the graph. We do this iteratively
            //  to avoid overflowing the stack.
            // After we have type information for all the types in the graph, we then walk over all
            //  the types again, and construct their method groups, since we have the necessary
            //  information to determine which methods are ignored.
            while (args.TypesToInitialize.Count > 0)
            {
                var kvp = args.TypesToInitialize.First;
                args.TypesToInitialize.Remove(kvp.Key);

                args.Definition = kvp.Value;
                TypeInformation.TryCreate(
                    kvp.Key, args, MakeTypeInfo
                    );
            }

            foreach (var ti in args.SecondPass.Values)
            {
                ti.Initialize();
                ti.ConstructMethodGroups();
            }

            if (!TypeInformation.TryGet(identifier, out result))
            {
                return(null);
            }
            else
            {
                return(result);
            }
        }
Beispiel #2
0
        internal void CreateNull(
            MethodInfo info, MethodReference method,
            QualifiedMemberIdentifier identifier
            )
        {
            var args = new NullCacheEntryArgs {
                Info   = info,
                Method = method
            };

            Cache.TryCreate(identifier, args, MakeNullCacheEntry);
        }
Beispiel #3
0
 internal void CreateNull(
     MethodInfo info, MethodReference method,
     QualifiedMemberIdentifier identifier
     )
 {
     Cache.TryCreate(identifier, () => {
         return(new Entry {
             Identifier = identifier,
             Info = info,
             Reference = method,
             Expression = null
         });
     });
 }
Beispiel #4
0
        void ITypeInfoSource.CacheProxyNames(MemberReference mr)
        {
            var fullName = mr.DeclaringType.FullName;

            ProxiesByName.TryCreate(fullName, () => {
                var icap = mr.DeclaringType as Mono.Cecil.ICustomAttributeProvider;
                if (icap == null)
                {
                    return(null);
                }

                CustomAttribute proxyAttribute = null;
                for (int i = 0, c = icap.CustomAttributes.Count; i < c; i++)
                {
                    var ca = icap.CustomAttributes[i];
                    if ((ca.AttributeType.Name == "JSProxy") && (ca.AttributeType.Namespace == "JSIL.Proxy"))
                    {
                        proxyAttribute = ca;
                        break;
                    }
                }

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

                string[] proxyTargets = null;
                var args = proxyAttribute.ConstructorArguments;

                foreach (var arg in args)
                {
                    switch (arg.Type.FullName)
                    {
                    case "System.Type":
                        proxyTargets = new string[] { ((TypeReference)arg.Value).FullName };

                        break;

                    case "System.Type[]": {
                        var values   = (CustomAttributeArgument[])arg.Value;
                        proxyTargets = new string[values.Length];
                        for (var i = 0; i < proxyTargets.Length; i++)
                        {
                            proxyTargets[i] = ((TypeReference)values[i].Value).FullName;
                        }

                        break;
                    }

                    case "System.String": {
                        proxyTargets = new string[] { (string)arg.Value };

                        break;
                    }

                    case "System.String[]": {
                        var values   = (CustomAttributeArgument[])arg.Value;
                        proxyTargets = (from v in values select(string) v.Value).ToArray();

                        break;
                    }
                    }
                }

                return(proxyTargets);
            });
        }
Beispiel #5
0
        public TypeInfo GetTypeInformation(TypeReference type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            TypeInfo result;
            var      identifier = new TypeIdentifier(type);

            if (TypeInformation.TryGet(identifier, out result))
            {
                return(result);
            }

            var fullName = type.FullName;

            var moreTypes         = new Dictionary <TypeIdentifier, TypeDefinition>();
            var typesToInitialize = new OrderedDictionary <TypeIdentifier, TypeDefinition>();
            var secondPass        = new Dictionary <TypeIdentifier, TypeInfo>();

            EnqueueType(typesToInitialize, type);

            // We must construct type information in two passes, so that method group construction
            //  behaves correctly and ignores all the right methods.
            // The first pass walks all the way through the type graph (starting with the current type),
            //  ensuring we have type information for all the types in the graph. We do this iteratively
            //  to avoid overflowing the stack.
            // After we have type information for all the types in the graph, we then walk over all
            //  the types again, and construct their method groups, since we have the necessary
            //  information to determine which methods are ignored.
            while (typesToInitialize.Count > 0)
            {
                var kvp = typesToInitialize.First;
                typesToInitialize.Remove(kvp.Key);

                TypeInformation.TryCreate(
                    kvp.Key, () => {
                    var constructed = ConstructTypeInformation(kvp.Key, kvp.Value, moreTypes);
                    secondPass.Add(kvp.Key, constructed);

                    foreach (var more in moreTypes)
                    {
                        EnqueueType(typesToInitialize, more.Value);
                    }
                    moreTypes.Clear();

                    return(constructed);
                }
                    );
            }

            foreach (var ti in secondPass.Values)
            {
                ti.Initialize();
                ti.ConstructMethodGroups();
            }

            if (!TypeInformation.TryGet(identifier, out result))
            {
                return(null);
            }
            else
            {
                return(result);
            }
        }
Beispiel #6
0
        void ITypeInfoSource.CacheProxyNames(MemberReference mr)
        {
            var fullName = mr.DeclaringType.FullName;

            ProxiesByName.TryCreate(fullName, mr, MakeProxiesByName);
        }