internal static void Initialize(ModuleDefinition moduleDefinition) { ModuleDefinition = moduleDefinition; typeType = ModuleDefinition.Import(typeof(Type)); taskType = ModuleDefinition.Import(typeof(Task)); getTypeFromRuntimeHandleMethod = ModuleDefinition.Import(typeType.Resolve().Methods.Single(x => x.Name == "GetTypeFromHandle")); typeGetMethod = ModuleDefinition.Import(typeType.Resolve().Methods.Single(x => x.Name == "GetMethod" && x.Parameters.Count == 5)); taskTType = ModuleDefinition.Import(typeof(Task<>)); taskFromResult = ModuleDefinition.Import(taskType.Resolve().Methods.Single(x => x.Name == "FromResult")); }
/// <summary> /// Transform open generic types to closed instantiation using context information. /// As an example, if B{T} inherits from A{T}, running it with B{C} as context and A{B.T} as type, ti will return A{C}. /// </summary> public static TypeReference Process(TypeReference context, TypeReference type) { if (type == null) return null; var genericInstanceTypeContext = context as GenericInstanceType; if (genericInstanceTypeContext == null) return type; if (genericInstanceTypeContext.ContainsGenericParameter()) return type; // Build dictionary that will map generic type to their real implementation type var resolvedType = context.Resolve(); var genericTypeMapping = new Dictionary<TypeReference, TypeReference>(); for (int i = 0; i < resolvedType.GenericParameters.Count; ++i) { var genericParameter = context.GetElementType().Resolve().GenericParameters[i]; genericTypeMapping.Add(genericParameter, genericInstanceTypeContext.GenericArguments[i]); } var visitor = new ResolveGenericsVisitor(genericTypeMapping); var result = visitor.VisitDynamic(type); // Make sure type is closed now if (result.ContainsGenericParameter()) throw new InvalidOperationException("Unsupported generic resolution."); return result; }
private void AddRole(TypeReference role) { var memberReader = new MemberReaderVisitor(); role.Resolve().Accept(memberReader); var roleMembers = memberReader.Members.Select(member => MakeRoleMember(role, member)); AddRoleMembers(role, roleMembers); }
/// <summary> /// Is the given attribute type ApplicationRootAttribute or derived of that type? /// </summary> private bool IsApplicationRootAttribute(TypeReference attributeType) { var typeDef = attributeType.Resolve(); if (typeDef == null) { return(false); } // Try the cache bool result; if (isApplicationRootTypes.TryGetValue(typeDef, out result)) { return(result); } // No in cache yet, find out if ((typeDef.Namespace == AttributeConstants.Dot42AttributeNamespace) && (typeDef.Name == AttributeConstants.ApplicationRootAttributeName)) { result = true; } else { // Try base type result = (typeDef.BaseType != null) && IsApplicationRootAttribute(typeDef.BaseType); } isApplicationRootTypes[typeDef] = result; return(result); }
private TypeDefinition ResolveType(TypeReference aRef) { var xDef = aRef as TypeDefinition; if (xDef != null) { return xDef; } #if DEBUG var xArray = aRef as ArrayType; if (xArray != null) { throw new NotSupportedException("Reader.ResolveType doesnt support ArrayTypes"); } var xPointer = aRef as PointerType; if (xPointer != null) { throw new NotSupportedException("Reader.ResolveType doesnt support PointerTypes"); } //var xReference = aRef as ReferenceType; //if (xReference != null) //{ // throw new NotSupportedException("Reader.ResolveType doesnt support ReferenceTypes"); //} #endif return aRef.Resolve(); }
public Cecil.MethodDefinition MethodDefinition(AnalysisNet.Types.MethodDefinition methodDefinition) { Cecil.MethodDefinition cecilMethodDefinition = new Cecil.MethodDefinition(methodDefinition.Name, 0, Context.CurrentModule.TypeSystem.Void); GenerateMethodAttributes(methodDefinition, cecilMethodDefinition); cecilMethodDefinition.CreateGenericParameters(methodDefinition.GenericParameters.Count); Cecil.TypeReference returnType = ReferenceGenerator.TypeReference(methodDefinition.ReturnType); cecilMethodDefinition.ReturnType = returnType; AddConstraintsToGenericParameters(methodDefinition, cecilMethodDefinition); Cecil.TypeReference typeRef = ReferenceGenerator.TypeReference(methodDefinition.ContainingType); Cecil.TypeDefinition containingType = typeRef.Resolve(); cecilMethodDefinition.DeclaringType = containingType as Cecil.TypeDefinition; SetOverrides(methodDefinition, cecilMethodDefinition); SetCustomAttributes(methodDefinition.Attributes, cecilMethodDefinition.CustomAttributes); IDictionary <AnalysisNet.ThreeAddressCode.Values.IVariable, Cecil.ParameterDefinition> parameterDefinitions = CreateParameters(methodDefinition, cecilMethodDefinition); if (methodDefinition.HasBody) { cecilMethodDefinition.Body.MaxStackSize = methodDefinition.Body.MaxStack; cecilMethodDefinition.Body.InitLocals = methodDefinition.Body.LocalVariables.Count > 0; IDictionary <AnalysisNet.ThreeAddressCode.Values.IVariable, Cecil.Cil.VariableDefinition> variableDefinitions = CreateLocalVariables(methodDefinition, cecilMethodDefinition); InstructionGenerator instructionGenerator = new InstructionGenerator(ReferenceGenerator); // analysis-net instruction -> [cecil instruction] IDictionary <AnalysisNet.Bytecode.Instruction, IList <Cecil.Cil.Instruction> > mapInstructions = instructionGenerator.CreateInstructions(methodDefinition, cecilMethodDefinition, variableDefinitions, parameterDefinitions); CreateExceptionHandlers(mapInstructions, methodDefinition.Body, cecilMethodDefinition.Body); } return(cecilMethodDefinition); }
/// <summary> /// Determines whether the specified value type is blittable. /// </summary> /// <param name="typeReference">The type reference.</param> /// <param name="marshalInfo">The marshal information.</param> /// <returns></returns> private static bool IsValueTypeBlittable(TypeReference typeReference, MarshalInfo marshalInfo) { bool isBlittable; if (blittableValueTypes.TryGetValue(typeReference, out isBlittable)) return isBlittable; var typeDefinition = typeReference.Resolve(); // Only value types are blittable if (typeDefinition.IsValueType) { isBlittable = true; if (!typeDefinition.IsEnum && !typeDefinition.IsExplicitLayout) { // Check if every field is blittable foreach (var field in typeDefinition.Fields) { if (field.IsStatic) continue; var fieldType = ResolveGenericsVisitor.Process(typeReference, field.FieldType); if (!IsBlittable(fieldType, field.HasMarshalInfo ? field.MarshalInfo : null)) { isBlittable = false; break; } } } } blittableValueTypes[typeReference] = isBlittable; return isBlittable; }
public static bool IsAssignableFrom(this TypeReference baseType, TypeReference type, Action<string> logger = null) { if (type.IsGenericParameter) return baseType.CompareTo(type); return baseType.Resolve().IsAssignableFrom(type.Resolve(), logger); }
public static string Get(TypeReference type, Dictionary<FieldReference, string> fieldNames) { if (!type.IsValueType || type.IsNullable()) { return "null"; } if (type.IsPrimitive) { var mdt = type.MetadataType; switch (mdt) { case MetadataType.Boolean: return "false"; case MetadataType.IntPtr: case MetadataType.UIntPtr: case MetadataType.Int16: case MetadataType.Int32: case MetadataType.UInt16: case MetadataType.UInt32: case MetadataType.Byte: case MetadataType.SByte: case MetadataType.Single: case MetadataType.Double: case MetadataType.Char: return "0"; case MetadataType.Int64: case MetadataType.UInt64: return "[0, 0]"; default: throw new NotImplementedException("Cannot handle: " + mdt); } } if (type.Resolve().IsEnum) { return "0"; } var fields = type.EnumResolvedFields().Where(x => !x.Resolve().IsStatic).ToArray(); var defaultValue = "{" + string.Join(",", fields.Where(x => fieldNames.ContainsKey(x)) .Select(x => fieldNames[x] + ":" + Get(x.FieldType, fieldNames))) + "}"; return defaultValue; }
public AspectWeaver(TypeReference aspectType) { _type = aspectType.Resolve(); _onExecute = _type.Methods.FirstOrDefault(m => m.Name == "OnExecute"); _onComplete = _type.Methods.FirstOrDefault(m => m.Name == "OnComplete"); _onException = _type.Methods.FirstOrDefault(m => m.Name == "OnException"); _requiresAspectInstance = (_onExecute != null && !_onExecute.IsStatic) || (_onComplete != null && !_onComplete.IsStatic) || (_onException != null && !_onException.IsStatic); if (_requiresAspectInstance) { _aspectCtor = _type.Methods.FirstOrDefault(m => m.IsConstructor && !m.HasParameters); if (_aspectCtor == null) { throw new Exception(String.Format("Parameterless constructor required for {0}.", _type.Name)); } } _requiresCorrelationVariable = _onExecute != null && _onExecute.IsStatic && !_onExecute.ReturnType.TypeMatches(typeof(void)); if (_requiresCorrelationVariable) { _correlationType = _onExecute.ReturnType; } _aspectInstanceVariableName = String.Format("aspectInstance_{0}", _type.Name); _correlationVariableName = String.Format("aspectCorrelation_{0}", _type.Name); _exceptionVariableName = String.Format("aspectException_{0}", _type.Name); }
internal static void AddBaseTypes(SharpTreeNodeCollection children, TypeReference type) { var def = type.Resolve(); if (def.BaseType != null) children.Add(new BaseTypesEntryNode(ResolveWithTypes(def.BaseType, type), false)); foreach (TypeReference i in def.Interfaces) children.Add(new BaseTypesEntryNode(ResolveWithTypes(i, type), true)); }
internal static bool IsPublic (TypeReference typeref) { if (typeref == null) throw new ArgumentNullException ("typeref"); TypeDefinition td = typeref.Resolve (); return td.IsPublic; }
public override TypeReference Visit(TypeReference type) { var typeDefinition = type.Resolve(); if (typeDefinition.IsValueType && !type.IsValueType) type.IsValueType = typeDefinition.IsValueType; return base.Visit(type); }
/// <summary> /// Is the given type an enum or struct? /// </summary> private static bool IsEnumOrStruct(TypeReference type) { if (type.IsPrimitive) return false; if (!type.IsDefinitionOrReference()) return false; var typeDef = type.Resolve(); return (typeDef != null) && (typeDef.IsEnum || typeDef.IsValueType); }
public void Add(Mono.Cecil.TypeReference type) { // Add all methods of type. Mono.Cecil.TypeDefinition type_defintion = type.Resolve(); foreach (Mono.Cecil.MethodDefinition definition in type_defintion.Methods) { Add(definition); } }
private void InterceptMethod(ILProcessor processor, TypeReference typeReference, Instruction instruction, string name) { var typeDefinition = typeReference.Resolve(); var attributeConstructor = typeDefinition.Methods.First(x => x.Name == ".ctor"); var attributeMethod = typeDefinition.Methods.First(x => x.Name == name); processor.InsertBefore(instruction, processor.Create(OpCodes.Newobj, attributeConstructor)); processor.InsertBefore(instruction, processor.Create(OpCodes.Call, _getCurrentMethod)); processor.InsertBefore(instruction, processor.Create(OpCodes.Call, attributeMethod)); }
public BaseTypesEntryNode(TypeReference tr, bool isInterface) { if (tr == null) throw new ArgumentNullException("tr"); this.tr = tr; this.def = tr.Resolve(); this.isInterface = isInterface; this.LazyLoading = true; }
public MemberResolver(TypeReference target, ModuleDefinition targetModule = null) { if (target == null) throw new ArgumentNullException("target"); Target = target; Module = targetModule ?? Target.Module; Source = Target.Resolve(); TargetWithArguments = Target as GenericInstanceType; _map = new GenericParametersMap(Source, TargetWithArguments); }
public static TypeDefinition ToDef(this Mono.Cecil.TypeReference tr) { var res = tr.Resolve(); if (res == null) { throw new InvalidOperationException(); } return(res); }
public WindowsRuntimeDelegateMarshalInfoWriter(TypeReference type) : base(type) { TypeDefinition definition = type.Resolve(); if (!Extensions.IsDelegate(definition)) { throw new ArgumentException(string.Format("WindowsRuntimeDelegateMarshalInfoWriter cannot marshal non-delegate type {0}.", type.FullName)); } this._typeResolver = Unity.IL2CPP.ILPreProcessor.TypeResolver.For(type); if (<>f__am$cache0 == null) {
public void WriteComInterfaceFor(TypeReference type) { this._writer.WriteCommentedLine(type.FullName); this.WriteForwardDeclarations(type); string str = !type.Resolve().IsWindowsRuntime ? "Il2CppIUnknown" : "Il2CppIInspectable"; object[] args = new object[] { Naming.ForTypeNameOnly(type), str }; this._writer.WriteLine("struct NOVTABLE {0} : {1}", args); using (new BlockWriter(this._writer, true)) { this._writer.WriteStatement("static const Il2CppGuid IID"); Unity.IL2CPP.ILPreProcessor.TypeResolver typeResolver = Unity.IL2CPP.ILPreProcessor.TypeResolver.For(type); foreach (MethodDefinition definition in type.Resolve().Methods) { MethodReference method = typeResolver.Resolve(definition); this._writer.Write(GetSignature(method, method, typeResolver, null)); this._writer.WriteLine(" = 0;"); } } }
public NetTypeReference Visit(TypeReference type, ResolveData data) { var typeDef = type.Resolve(); if (typeDef == null) { throw new ImportException(string.Format("Cannot resolve type {0}", type.FullName)); } return(Visit(typeDef, data)); }
public ChangeFieldReferencesVisitor(FieldDefinition sourceField, TypeReference target, MethodDefinition stateGetter) { if (sourceField == null) throw new ArgumentNullException("sourceField"); if (target == null) throw new ArgumentNullException("target"); if (stateGetter == null) throw new ArgumentNullException("stateField"); if (sourceField.DeclaringType == target.Resolve()) throw new InvalidOperationException(); _sourceField = sourceField; _target = target; _stateGetter = ResolveStateGetter(stateGetter); }
public TypeReference GetSerializer(TypeReference objectType) { var resolvedObjectType = objectType.Resolve(); if (resolvedObjectType != null && resolvedObjectType.IsEnum) { return genericEnumSerializerType.MakeGenericType(objectType); } return null; }
private void SetDeclaringType(AnalysisNet.Types.TypeDefinition typeDefinition, Cecil.TypeDefinition cecilDef) { Cecil.TypeReference declaringTypeRef = typeDefinition.ContainingType == null ? null : ReferenceGenerator.TypeReference(typeDefinition.ContainingType); if (declaringTypeRef != null) { Cecil.TypeDefinition declaringType = declaringTypeRef.Resolve(); declaringType.NestedTypes.Add(cecilDef); cecilDef.DeclaringType = declaringType; } }
/// <summary> /// Determines whether a specified type inherits from EventHandler /// somewhere along it's hierarchy. /// </summary> /// <param name="type">The type to check.</param> public bool IsEvent(TypeReference type) { if (type == null) return false; else if (type.FullName == "System.EventHandler") return true; else if (type.FullName == "System.Object") return false; else return this.IsEvent(type.Resolve().BaseType); }
static TypeDefinition InnerResolve(TypeReference reference) { try { return reference.Resolve(); } catch (Exception exception) { throw new Exception(string.Format("Could not resolve '{0}'.", reference.FullName), exception); } }
/// <summary> /// Gets the type definition containing all the methods for the given type. /// </summary> /// <returns></returns> TypeDefinition GetMethodTypeDefinition(TypeReference typeReference) { if (typeReference is ArrayType) { // Return ArrayType return(corlib.MainModule.GetType(typeof(Array).FullName)); } // Default: resolve to get real type return(typeReference.Resolve()); }
static TypeDefinition InnerResolve(TypeReference reference) { try { return reference.Resolve(); } catch (Exception exception) { throw new Exception($"Could not resolve '{reference.FullName}'.", exception); } }
void InitialiseReferences() { dateTimeType = ModuleDefinition.Import(typeof (DateTime)); var dateTimeDefinition = dateTimeType.Resolve(); nowMethod = ModuleDefinition.Import(dateTimeDefinition.Methods.First(x => x.Name == "get_Now")); toLongTimeStringMethod = ModuleDefinition.Import(dateTimeDefinition.Methods.First(x => x.Name == "ToLongTimeString")); var stringType = ModuleDefinition.Import(typeof(string)).Resolve(); concatMethod = ModuleDefinition.Import(stringType.Methods.First(x => x.Name == "Concat" && x.Parameters.Count == 2)); var debugType = ModuleDefinition.Import(typeof(Debug)).Resolve(); writLineMethod = ModuleDefinition.Import(debugType.Methods.First(x => x.Name == "WriteLine" && x.Parameters.Count == 1 && x.Parameters[0].ParameterType.Name == "String")); }
public MethodReference GetOptionalMethodReference(TypeReference typeReference, Func<MethodDefinition, bool> predicate) { var typeDefinition = typeReference.Resolve(); MethodDefinition methodDefinition; do { methodDefinition = typeDefinition.Methods.FirstOrDefault(predicate); typeDefinition = typeDefinition.BaseType == null ? null : typeDefinition.BaseType.Resolve(); } while (methodDefinition == null && typeDefinition != null); return null != methodDefinition ? moduleDefinition.Import(methodDefinition) : null; }
public TypeReference RetrieveSelfType(TypeReference selfTypeHost) { var definition = selfTypeHost.Resolve(); if (definition == null) return null; // the "role" could be a generic parameter foreach (var parameter in definition.GenericParameters) { if (IsSelfTypeParameter(parameter)) { return ((GenericInstanceType)selfTypeHost).GenericArguments[parameter.Position]; } } return null; }
/// <summary> /// Gets the underlying type, if the specified type is an enum. /// Otherwise, returns null. /// </summary> public static TypeReference GetEnumUnderlyingType(TypeReference enumType) { // unfortunately we cannot rely on enumType.IsValueType here - it's not set when the instruction operand is a typeref (as opposed to a typespec) if (enumType != null && !IsArrayPointerOrReference(enumType)) { // value type might be an enum TypeDefinition typeDef = enumType.Resolve() as TypeDefinition; if (typeDef != null && typeDef.IsEnum) { return typeDef.Fields.Single(f => !f.IsStatic).FieldType; } } return null; }
private static bool DoesTypeEnheritFrom(TypeReference type, string typeName) { while (type != null) { if (type.FullName == typeName) { return true; } type = type.Resolve().BaseType; } return false; }
static void ProcessType(ModuleDefinition moduleDefinition, TypeDefinition type) { foreach (var toRemove in type.Properties.Where(x => x.IsCompilerGenerated()).ToList()) { type.Properties.Remove(toRemove); } foreach (var toRemove in type.Methods.Where(x => x.IsCompilerGenerated() && !x.Name.StartsWith("get_") && !x.Name.StartsWith("set_")).ToList()) { type.Methods.Remove(toRemove); } foreach (var toRemove in type.Fields.Where(x => x.IsCompilerGenerated()).ToList()) { type.Fields.Remove(toRemove); } foreach (var property in type.Properties) { property.RemoveUnwantedAttributes(); } foreach (var field in type.Fields) { field.RemoveUnwantedAttributes(); } var exceptionReference = new TypeReference("System", "Exception", moduleDefinition.TypeSystem.String.Module, moduleDefinition.TypeSystem.String.Scope); exceptionReference = moduleDefinition.Import(exceptionReference); var ctor = moduleDefinition.Import(exceptionReference.Resolve().GetConstructors().First(c => !c.HasParameters)); foreach (var method in type.Methods) { method.RemoveUnwantedAttributes(); if (method.HasBody) { //todo: preserve a single pdb line var body = method.Body; var validSequencePoint = method.GetValidSequencePoint(); body.Variables.Clear(); body.ExceptionHandlers.Clear(); body.Instructions.Clear(); body.Instructions.Add(Instruction.Create(OpCodes.Newobj, ctor)); var instruction = Instruction.Create(OpCodes.Throw); if (validSequencePoint != null) { instruction.SequencePoint = validSequencePoint; } body.Instructions.Add(instruction); } } }
public MethodReference GetMethodReference(TypeReference typeReference, Func<MethodDefinition, bool> predicate) { TypeDefinition typeDefinition = typeReference.Resolve(); MethodDefinition methodDefinition; do { methodDefinition = typeDefinition.Methods.FirstOrDefault(predicate); typeDefinition = typeDefinition.BaseType?.Resolve(); } while (methodDefinition == null && typeDefinition != null); return _moduleDefinition.Import(methodDefinition); }
private bool CanInferTypeOfDelegateCreation(TypeReference type) { if (type.IsGenericInstance) { return true; } TypeDefinition resolvedLeftType = type.Resolve(); if (resolvedLeftType != null && !resolvedLeftType.IsAbstract) { return true; } return false; }
public static Type CreateBlittableTypeMono(Mono.Cecil.TypeReference hostType, bool declare_parent_chain) { try { Mono.Cecil.TypeDefinition td = hostType.Resolve(); String name; SR.TypeFilter tf; // Declare parent chain since TypeBuilder works top down not bottom up. if (declare_parent_chain) { name = hostType.FullName; name = name.Replace('+', '.'); tf = new SR.TypeFilter((Type t, object o) => { return(t.FullName == name); }); } else { name = hostType.Name; tf = new SR.TypeFilter((Type t, object o) => { return(t.Name == name); }); } // Find if blittable type for hostType was already performed. Data data = new Data(); Type[] types = data.mb.FindTypes(tf, null); // If blittable type was not created, create one with all fields corresponding // to that in host, with special attention to arrays. if (types.Length == 0) { if (hostType.IsArray) { // Recurse Type elementType = CreateBlittableTypeMono(hostType.GetElementType(), true); object array_obj = Array.CreateInstance(elementType, 0); Type array_type = array_obj.GetType(); TypeBuilder tb = null; tb = data.mb.DefineType( array_type.Name, SR.TypeAttributes.Public | SR.TypeAttributes.Sealed | SR.TypeAttributes.SequentialLayout | SR.TypeAttributes.Serializable, typeof(ValueType)); return(tb.CreateType()); } else if (Campy.Types.Utils.ReflectionCecilInterop.IsStruct(hostType) || !hostType.IsValueType) { TypeBuilder tb = null; tb = data.mb.DefineType( name, SR.TypeAttributes.Public | SR.TypeAttributes.Sealed | SR.TypeAttributes.SequentialLayout | SR.TypeAttributes.Serializable, typeof(ValueType)); var fields = td.Fields; foreach (var field in fields) { if (field.FieldType.IsArray) { // Convert byte, int, etc., in host type to pointer in blittable type. // With array, we need to also encode the length. tb.DefineField(field.Name, typeof(IntPtr), SR.FieldAttributes.Public); tb.DefineField(field.Name + "Len0", typeof(Int32), SR.FieldAttributes.Public); } else { // For non-array type fields, just define the field as is. tb.DefineField(field.Name, Campy.Types.Utils.ReflectionCecilInterop.ConvertToSystemReflectionType(field.FieldType), SR.FieldAttributes.Public); } } return(tb.CreateType()); } else { return(null); } } else { return(types[0]); } } catch { return(null); } }
/// <summary> /// Mark all base types and externally visible members reachable /// </summary> private static void Walk(ReachableContext context, TypeReference type) { // Generic parameters Walk(context, (IGenericParameterProvider)type); TypeDefinition typeDef; TypeSpecification typeSpec; GenericParameter genericParam; if ((typeDef = type as TypeDefinition) != null) { // Mark base type reachable typeDef.BaseType.MarkReachable(context); // Mark declaring type reachable typeDef.DeclaringType.MarkReachable(context); // Mark implemented interfaces reachable if (typeDef.HasInterfaces) { foreach (var intf in typeDef.Interfaces.Select(x => x.Interface)) { intf.MarkReachable(context); } } // If is an an attribute include related types if (typeDef.IsAttribute()) { GetDot42InternalType(context, "IAttribute").MarkReachable(context); GetDot42InternalType(context, "IAttributes").MarkReachable(context); GetDot42InternalType(context, "IAnnotationType").MarkReachable(context); } else if (typeDef.IsEnum) { var boxingType = GetDot42InternalType(context, "Boxing"); boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context)); } // Default & class ctor typeDef.FindDefaultCtor().MarkReachable(context); typeDef.GetClassCtor().MarkReachable(context); // Visit externally visible members if (typeDef.HasEvents) { foreach (var evt in typeDef.Events) { if ((!evt.IsReachable) && context.Include(evt)) { evt.MarkReachable(context); } } } if (typeDef.HasFields) { foreach (var field in typeDef.Fields) { if ((!field.IsReachable) && context.Include(field)) { field.MarkReachable(context); } } } if (typeDef.HasMethods) { foreach (var method in typeDef.Methods) { if ((!method.IsReachable) && context.Include(method)) { method.MarkReachable(context); } } } if (typeDef.HasProperties) { foreach (var prop in typeDef.Properties) { if ((!prop.IsReachable) && context.Include(prop)) { prop.MarkReachable(context); } } } // Custom attributes Walk(context, (ICustomAttributeProvider)typeDef); // Walk imported java classes CustomAttribute javaImportAttr; if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null) { var javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value; ClassFile javaClass; if (context.TryLoadClass(javaClassName, out javaClass)) { javaClass.MarkReachable(context); } } // Dex imported interfaces should have all their methods marked reachable. if (typeDef.IsInterface && typeDef.HasDexImportAttribute()) { typeDef.Methods.ForEach(x => x.MarkReachable(context)); } // Record in context and create class builder context.RecordReachableType(typeDef); } else if ((typeSpec = type as TypeSpecification) != null) { // Element typeSpec.ElementType.MarkReachable(context); // Generic instance GenericInstanceType git; FunctionPointerType fpt; RequiredModifierType reqModType; OptionalModifierType optModType; if ((git = typeSpec as GenericInstanceType) != null) { if (git.ElementType.IsNullableT()) { var typeofT = git.GenericArguments[0].Resolve(context); if (typeofT != null) { typeofT.UsedInNullableT = true; } } Walk(context, (IGenericInstance)git); } else if ((fpt = typeSpec as FunctionPointerType) != null) { Walk(context, fpt.ReturnType); } else if ((reqModType = typeSpec as RequiredModifierType) != null) { reqModType.ModifierType.MarkReachable(context); } else if ((optModType = typeSpec as OptionalModifierType) != null) { optModType.ModifierType.MarkReachable(context); } } else if ((genericParam = type as GenericParameter) != null) { // Owner var owner = (MemberReference)genericParam.Owner; owner.MarkReachable(context); // Constraints if (genericParam.HasConstraints) { foreach (TypeReference constraint in genericParam.Constraints) { constraint.MarkReachable(context); } } } else { // Try to resolve type.Resolve(context).MarkReachable(context); } }
/// <summary> /// Gets the type for the given reference. /// </summary> public TypeDefinition GetTypeDefinition(TypeReference typeRef) { return(typeRef.Resolve()); }
/// <summary> /// Mark all base types and externally visible members reachable /// </summary> private static void Walk(ReachableContext context, TypeReference type) { // Generic parameters Walk(context, (IGenericParameterProvider)type); TypeDefinition typeDef; TypeSpecification typeSpec; GenericParameter genericParam; if ((typeDef = type as TypeDefinition) != null) { var isUsedInSerialization = typeDef.IsUsedInSerialization && !type.IsPrimitive && !typeDef.IsEnum && !type.Namespace.StartsWith("System"); // Mark base type reachable typeDef.BaseType.MarkReachable(context, isUsedInSerialization); // Mark declaring type reachable typeDef.DeclaringType.MarkReachable(context); // Mark implemented interfaces reachable if (typeDef.HasInterfaces) { foreach (var intf in typeDef.Interfaces.Select(x => x.InterfaceType)) { intf.MarkReachable(context); } } // If this is an attribute, include related types if (typeDef.IsAttribute()) { GetDot42InternalType(context, "IAttribute").MarkReachable(context); GetDot42InternalType(context, "IAttributes").MarkReachable(context); } else if (typeDef.IsEnum) { var boxingType = GetDot42InternalType(context, "Boxing"); boxingType.Methods.Where(x => (x.Name == "UnboxInteger" || x.Name == "UnboxLong")).ForEach(x => x.MarkReachable(context)); } // Default & class ctor typeDef.FindDefaultCtor().MarkReachable(context); typeDef.GetClassCtor().MarkReachable(context); // Visit externally visible members if (typeDef.HasEvents) { foreach (var evt in typeDef.Events) { if ((!evt.IsReachable) && context.Include(evt)) { evt.MarkReachable(context); } } } if (typeDef.HasFields) { foreach (var field in typeDef.Fields) { // only public fields, so we don't pull any compiler generated stuff. var isSerializable = isUsedInSerialization && !field.IsStatic && field.IsPublic; if ((!field.IsReachable && context.Include(field)) || (!field.IsUsedInSerialization && isSerializable)) { field.MarkReachable(context, isUsedInSerialization); } } } if (typeDef.HasMethods) { foreach (var method in typeDef.Methods) { if ((!method.IsReachable) && context.Include(method)) { method.MarkReachable(context); } } } if (typeDef.HasProperties) { foreach (var prop in typeDef.Properties) { var isSerializable = isUsedInSerialization && prop.HasThis; if ((!prop.IsReachable && context.Include(prop) || (!prop.IsUsedInSerialization && isSerializable))) { prop.MarkReachable(context, isUsedInSerialization); } } } // Custom attributes Walk(context, (ICustomAttributeProvider)typeDef); // Walk imported java classes CustomAttribute javaImportAttr; if ((javaImportAttr = typeDef.GetJavaImportAttribute()) != null) { var javaClassName = (string)javaImportAttr.ConstructorArguments[0].Value; ClassFile javaClass; if (context.TryLoadClass(javaClassName, out javaClass)) { javaClass.MarkReachable(context); } } // Dex imported interfaces should have all their methods marked reachable. if (typeDef.IsInterface && typeDef.HasDexImportAttribute()) { typeDef.Methods.ForEach(x => x.MarkReachable(context)); } // Record in context context.RecordReachableType(typeDef); } else if ((typeSpec = type as TypeSpecification) != null) { // Element typeSpec.ElementType.MarkReachable(context, typeSpec.IsUsedInSerialization); // Generic instance GenericInstanceType git; FunctionPointerType fpt; RequiredModifierType reqModType; OptionalModifierType optModType; if ((git = typeSpec as GenericInstanceType) != null) { if (git.ElementType.IsNullableT()) { var typeofT = git.GenericArguments[0].Resolve(context); if (typeofT != null && !typeofT.UsedInNullableT) { typeofT.UsedInNullableT = true; DLog.Debug(DContext.CompilerAssemblyResolver, "found System.Nullable<{0}>", typeofT.FullName); } } Walk(context, (IGenericInstance)git); } else if ((fpt = typeSpec as FunctionPointerType) != null) { Walk(context, fpt.ReturnType); } else if ((reqModType = typeSpec as RequiredModifierType) != null) { reqModType.ModifierType.MarkReachable(context); } else if ((optModType = typeSpec as OptionalModifierType) != null) { optModType.ModifierType.MarkReachable(context); } } else if ((genericParam = type as GenericParameter) != null) { genericParam.IsSerializedParameter = genericParam.HasSerializedParameterAttribute(); // Owner var owner = (MemberReference)genericParam.Owner; owner.MarkReachable(context); // Constraints if (genericParam.HasConstraints) { foreach (TypeReference constraint in genericParam.Constraints) { constraint.MarkReachable(context); } } } else { // Try to resolve type.Resolve(context).MarkReachable(context, type.IsUsedInSerialization); } }