// call after every method definition in analysisNetType is extracted private void ExtractPropertyDefinitions(AnalysisNet.Types.TypeDefinition analysisNetType, Cecil.TypeDefinition cecilType) { foreach (Cecil.PropertyDefinition cecilProperty in cecilType.Properties) { AnalysisNet.Types.PropertyDefinition ourProp = new AnalysisNet.Types.PropertyDefinition(cecilProperty.Name, ExtractType(cecilProperty.PropertyType)) { ContainingType = analysisNetType }; if (cecilProperty.GetMethod != null) { // It is a reference but we need the definition. // It is not safe to call ResolvedMethod at this point, the model is incomplete. AnalysisNet.Types.IMethodReference getterRef = ExtractMethod(cecilProperty.GetMethod); ourProp.Getter = analysisNetType.Methods.Where(methodDef => methodDef.MatchSignature(getterRef)).First(); } if (cecilProperty.SetMethod != null) { // It is a reference but we need the definition. // It is not safe to call ResolvedMethod at this point, the model is incomplete. AnalysisNet.Types.IMethodReference setterRef = ExtractMethod(cecilProperty.SetMethod); ourProp.Setter = analysisNetType.Methods.Where(methodDef => methodDef.MatchSignature(setterRef)).First(); } ExtractCustomAttributes(ourProp.Attributes, cecilProperty.CustomAttributes); analysisNetType.PropertyDefinitions.Add(ourProp); } }
public Cecil.TypeDefinition TypeDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { if (typeDefinition.Kind == AnalysisNet.Types.TypeDefinitionKind.Struct) { return(CreateStructDefinition(typeDefinition)); } else if (typeDefinition.Kind == AnalysisNet.Types.TypeDefinitionKind.Enum) { return(CreateEnumDefinition(typeDefinition)); } else if (typeDefinition.Kind == AnalysisNet.Types.TypeDefinitionKind.Interface) { return(CreateInterfaceDefinition(typeDefinition)); } else if (typeDefinition.Kind == AnalysisNet.Types.TypeDefinitionKind.Class) { return(CreateClassDefinition(typeDefinition)); } else if (typeDefinition.Kind == AnalysisNet.Types.TypeDefinitionKind.Delegate) { return(CreateDelegateDefinition(typeDefinition)); } throw new NotImplementedException(); }
public void PropertyDefinitions(AnalysisNet.Types.TypeDefinition analysisNetType, Cecil.TypeDefinition cecilTypeDef) { foreach (AnalysisNet.Types.PropertyDefinition analysisNetProp in analysisNetType.PropertyDefinitions) { Cecil.PropertyDefinition cecilProp = new Cecil.PropertyDefinition(analysisNetProp.Name, Cecil.PropertyAttributes.None, ReferenceGenerator.TypeReference(analysisNetProp.PropertyType)); if (analysisNetProp.Getter != null) { Cecil.MethodDefinition getterDef = ReferenceGenerator.MethodReference(analysisNetProp.Getter).Resolve(); cecilProp.GetMethod = getterDef; } if (analysisNetProp.Setter != null) { Cecil.MethodDefinition setterDef = ReferenceGenerator.MethodReference(analysisNetProp.Setter).Resolve(); cecilProp.SetMethod = setterDef; } SetCustomAttributes(analysisNetProp.Attributes, cecilProp.CustomAttributes); // Properties.Add sets this field //cecilProp.DeclaringType = ReferenceGenerator.TypeReference(analysisNetType).Resolve(); cecilTypeDef.Properties.Add(cecilProp); } }
private void AddInterfaceImplementations(AnalysisNet.Types.TypeDefinition typeDefinition, Cecil.TypeDefinition t) { foreach (AnalysisNet.Types.IBasicType inter in typeDefinition.Interfaces) { t.Interfaces.Add(new Cecil.InterfaceImplementation(ReferenceGenerator.TypeReference(inter))); } }
private AnalysisNet.Types.TypeDefinition ExtractClass(Cecil.TypeDefinition cecilType, AnalysisNet.Types.TypeKind typeKind, AnalysisNet.Types.TypeDefinitionKind typeDefinitionKind) { string name = UnmangleName(cecilType); AnalysisNet.Types.TypeDefinition type = new AnalysisNet.Types.TypeDefinition(name, typeKind, typeDefinitionKind); Cecil.TypeReference basedef = cecilType.BaseType; type.IsAbstract = cecilType.IsAbstract; type.IsSealed = cecilType.IsSealed; if (basedef != null) { type.Base = ExtractType(basedef) as AnalysisNet.Types.IBasicType; } ExtractCustomAttributes(type.Attributes, cecilType.CustomAttributes); ExtractGenericTypeParameters(type, cecilType); ExtractInterfaces(type.Interfaces, cecilType.Interfaces); ExtractFields(type, type.Fields, cecilType.Fields); ExtractMethods(type, type.Methods, cecilType.Methods); ExtractPropertyDefinitions(type, cecilType); ExtractExplicitMethodOverrides(type, cecilType); ExtractLayoutInformation(type, cecilType); return(type); }
private void ExtractMethods(AnalysisNet.Types.TypeDefinition containingType, IList <AnalysisNet.Types.MethodDefinition> dest, IEnumerable <Cecil.MethodDefinition> source) { foreach (Cecil.MethodDefinition methoddef in source) { string name = methoddef.Name; AnalysisNet.Types.MethodDefinition method = new AnalysisNet.Types.MethodDefinition(name, null); ExtractCustomAttributes(method.Attributes, methoddef.CustomAttributes); ExtractGenericMethodParameters(method, methoddef); ExtractParameters(method.Parameters, methoddef.Parameters); method.ReturnType = ExtractType(methoddef.ReturnType); if (methoddef.HasBody) { CodeProvider codeProvider = new CodeProvider(this); method.Body = codeProvider.ExtractBody(methoddef.Body); } method.Visibility = ExtractVisibilityKind(methoddef); method.IsStatic = methoddef.IsStatic; method.IsAbstract = methoddef.IsAbstract; method.IsVirtual = methoddef.IsVirtual; method.IsOverrider = (methoddef.IsAbstract || methoddef.IsVirtual) && !methoddef.IsNewSlot; method.IsFinal = methoddef.IsFinal; method.IsConstructor = methoddef.IsConstructor; method.IsExternal = methoddef.IsPInvokeImpl; method.ContainingType = containingType; dest.Add(method); } }
// the extracted type is added to the expected namespace // if cecilType is a nested type, we guarantee that we have already visited its declaring type private void ExtractTypeDefinition(Cecil.TypeDefinition cecilType, AnalysisNet.Assembly assembly, TypeExtractor typeExtractor) { // afaik it is not necessary to generate this class // for instance cci does not even load it although cecil does if (cecilType.Name.Equals("<Module>") && cecilType.BaseType == null) { return; } AnalysisNet.Types.TypeDefinition extractedType = typeExtractor.ExtractTypeDefinition(cecilType); typeDefinitions[cecilType] = extractedType; extractedType.ContainingAssembly = assembly; // analysis-net does not follow ecma standard for nested types // analysis-net expects to have nested types in their ContainingType.Types and share the same namespace that its enclosing type. // However, nested types should not be added to the ContainingNamespace.Types // If the type is not nested then the processed type is added to its namespace directly if (cecilType.DeclaringType != null) { AnalysisNet.Types.TypeDefinition containingType = typeDefinitions[cecilType.DeclaringType]; extractedType.ContainingType = containingType; containingType.Types.Add(extractedType); extractedType.ContainingNamespace = containingType.ContainingNamespace; } else { AnalysisNet.Namespace ns = GetOrCreateNamespace(cecilType.Namespace); extractedType.ContainingNamespace = ns; ns.Types.Add(extractedType); } }
private void CreateFieldDefinitions(AnalysisNet.Types.TypeDefinition analysisNetDef, Cecil.TypeDefinition cecilDef) { foreach (AnalysisNet.Types.FieldDefinition field in analysisNetDef.Fields) { cecilDef.Fields.Add(CreateFieldDefinition(field)); } }
private void ExtractLayoutInformation(AnalysisNet.Types.TypeDefinition type, Cecil.TypeDefinition typeDefinition) { AnalysisNet.Types.LayoutKind kind; if (typeDefinition.IsAutoLayout) { kind = AnalysisNet.Types.LayoutKind.AutoLayout; } else if (typeDefinition.IsExplicitLayout) { kind = AnalysisNet.Types.LayoutKind.ExplicitLayout; } else if (typeDefinition.IsSequentialLayout) { kind = AnalysisNet.Types.LayoutKind.SequentialLayout; } else { throw new NotImplementedException(); } Model.Types.LayoutInformation layoutInformation = new AnalysisNet.Types.LayoutInformation(kind) { ClassSize = typeDefinition.ClassSize, PackingSize = typeDefinition.PackingSize }; type.LayoutInformation = layoutInformation; }
private void SetAttributes(AnalysisNet.Types.TypeDefinition typeDefinition, Cecil.TypeDefinition cecilDef) { cecilDef.IsAbstract = typeDefinition.IsAbstract; cecilDef.IsSealed = typeDefinition.IsSealed; if (typeDefinition.ContainingType != null) { cecilDef.IsNestedPublic = true; } else { cecilDef.IsPublic = true; } if (typeDefinition.LayoutInformation is AnalysisNet.Types.LayoutInformation layoutInfo) { if (layoutInfo.Kind == AnalysisNet.Types.LayoutKind.AutoLayout) { cecilDef.IsAutoLayout = true; } else if (layoutInfo.Kind == AnalysisNet.Types.LayoutKind.ExplicitLayout) { cecilDef.IsExplicitLayout = true; } else if (layoutInfo.Kind == AnalysisNet.Types.LayoutKind.SequentialLayout) { cecilDef.IsSequentialLayout = true; } cecilDef.PackingSize = layoutInfo.PackingSize; cecilDef.ClassSize = layoutInfo.ClassSize; } }
private Cecil.TypeDefinition CreateInterfaceDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { Cecil.TypeDefinition cecilDefinition = CreateClassDefinition(typeDefinition); cecilDefinition.Attributes |= Cecil.TypeAttributes.Interface; cecilDefinition.Attributes |= Cecil.TypeAttributes.Abstract; // todo: not sure about this cecilDefinition.Attributes &= ~Cecil.TypeAttributes.Class; return(cecilDefinition); }
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; } }
private void ExtractExplicitMethodOverrides(AnalysisNet.Types.TypeDefinition type, Cecil.TypeDefinition typeDefinition) { foreach (Cecil.MethodDefinition method in typeDefinition.Methods) { AnalysisNet.Types.IMethodReference implementingMethod = ExtractMethod(method); Mono.Collections.Generic.Collection <Cecil.MethodReference> overrides = method.Overrides; foreach (Cecil.MethodReference implemented in overrides) { AnalysisNet.Types.IMethodReference implementedMethod = ExtractMethod(implemented); AnalysisNet.Types.MethodImplementation methodImplementation = new AnalysisNet.Types.MethodImplementation(implementedMethod, implementingMethod); type.ExplicitOverrides.Add(methodImplementation); } } }
private AnalysisNet.Types.TypeDefinition ExtractInterface(Cecil.TypeDefinition cecilType) { string name = UnmangleName(cecilType); AnalysisNet.Types.TypeDefinition type = new AnalysisNet.Types.TypeDefinition(name, AnalysisNet.Types.TypeKind.ReferenceType, AnalysisNet.Types.TypeDefinitionKind.Interface) { IsAbstract = cecilType.IsAbstract, IsSealed = cecilType.IsSealed }; ExtractCustomAttributes(type.Attributes, cecilType.CustomAttributes); ExtractGenericTypeParameters(type, cecilType); ExtractInterfaces(type.Interfaces, cecilType.Interfaces); ExtractMethods(type, type.Methods, cecilType.Methods); ExtractPropertyDefinitions(type, cecilType); return(type); }
private static LinkedList <Model.Types.TypeDefinition> DFS(Model.Types.TypeDefinition typeDefinition, ISet <Model.Types.TypeDefinition> visited) { visited.Add(typeDefinition); if (typeDefinition.ContainingType == null || visited.Contains(typeDefinition.ContainingType)) { LinkedList <Model.Types.TypeDefinition> l = new LinkedList <Model.Types.TypeDefinition>(); l.AddLast(typeDefinition); return(l); } LinkedList <Model.Types.TypeDefinition> rec = DFS(typeDefinition.ContainingType, visited); rec.AddLast(typeDefinition); return(rec); }
private AnalysisNet.Types.TypeDefinition ExtractEnum(Cecil.TypeDefinition typedef) { string name = typedef.Name; AnalysisNet.Types.TypeDefinition type = new AnalysisNet.Types.TypeDefinition(name, AnalysisNet.Types.TypeKind.ValueType, AnalysisNet.Types.TypeDefinitionKind.Enum) { Base = ExtractType(typedef.BaseType) as AnalysisNet.Types.IBasicType, IsAbstract = typedef.IsAbstract, IsSealed = typedef.IsSealed }; Cecil.FieldDefinition valueField = typedef.Fields.Single(f => f.Name == "value__"); type.UnderlayingType = ExtractType(valueField.FieldType) as AnalysisNet.Types.IBasicType; ExtractCustomAttributes(type.Attributes, typedef.CustomAttributes); ExtractConstants(type, type.Fields, typedef.Fields); return(type); }
private Cecil.TypeDefinition CreateEnumDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { Cecil.TypeDefinition def = CreateClassDefinition(typeDefinition); def.IsSealed = true; foreach (Cecil.FieldDefinition field in def.Fields) { field.IsStatic = true; field.IsLiteral = true; field.HasDefault = true; field.FieldType.IsValueType = true; } Cecil.TypeReference underlyingType = ReferenceGenerator.TypeReference(typeDefinition.UnderlayingType); Cecil.FieldDefinition value__ = new Cecil.FieldDefinition("value__", Cecil.FieldAttributes.RTSpecialName | Cecil.FieldAttributes.SpecialName, underlyingType); def.Fields.Insert(0, value__); return(def); }
private Cecil.TypeDefinition CreateClassDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { string namespaceName = typeDefinition.ContainingType != null ? string.Empty : typeDefinition.ContainingNamespace.FullName; string name = typeDefinition.MetadataName(); Cecil.TypeDefinition t = new Cecil.TypeDefinition(namespaceName, name, Cecil.TypeAttributes.Class); SetAttributes(typeDefinition, t); t.CreateGenericParameters(typeDefinition.GenericParameters.Count); SetBaseType(typeDefinition, t); SetDeclaringType(typeDefinition, t); AddConstraintsToGenericParameters(typeDefinition, t); AddInterfaceImplementations(typeDefinition, t); CreateFieldDefinitions(typeDefinition, t); SetCustomAttributes(typeDefinition.Attributes, t.CustomAttributes); return(t); }
private void ExtractFields(AnalysisNet.Types.TypeDefinition containingType, IList <AnalysisNet.Types.FieldDefinition> dest, IEnumerable <Cecil.FieldDefinition> source) { foreach (Cecil.FieldDefinition fielddef in source) { string name = fielddef.Name; AnalysisNet.Types.IType type = ExtractType(fielddef.FieldType); AnalysisNet.Types.FieldDefinition field = new AnalysisNet.Types.FieldDefinition(name, type); byte[] newArray = new byte[fielddef.InitialValue.Length]; Array.Copy(fielddef.InitialValue, newArray, newArray.Length); field.InitialValue = newArray; ExtractCustomAttributes(field.Attributes, fielddef.CustomAttributes); field.Visibility = ExtractVisibilityKind(fielddef); field.IsStatic = fielddef.IsStatic; field.ContainingType = containingType; dest.Add(field); } }
private void ExtractConstants(AnalysisNet.Types.TypeDefinition containingType, IList <AnalysisNet.Types.FieldDefinition> dest, IEnumerable <Cecil.FieldDefinition> source) { source = source.Skip(1); foreach (Cecil.FieldDefinition constdef in source) { if (!constdef.HasConstant) { continue; } string name = constdef.Name; AnalysisNet.Types.FieldDefinition constant = new AnalysisNet.Types.FieldDefinition(name, containingType) { Value = new AnalysisNet.ThreeAddressCode.Values.Constant(constdef.Constant) { Type = containingType.UnderlayingType } }; constant.ContainingType = containingType; dest.Add(constant); } }
private Cecil.ModuleDefinition ResolveModule(AnalysisNet.Types.TypeDefinition typeDefinition) { return(Context.ModelMapping.AssembliesMap[typeDefinition.ContainingAssembly].MainModule); }
private Cecil.TypeDefinition CreateStructDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { Cecil.TypeDefinition cecilDefinition = CreateClassDefinition(typeDefinition); return(cecilDefinition); }
private void SetBaseType(AnalysisNet.Types.TypeDefinition typeDefinition, Cecil.TypeDefinition cecilDef) { Cecil.TypeReference baseType = typeDefinition.Base == null ? null : ReferenceGenerator.TypeReference(typeDefinition.Base); cecilDef.BaseType = baseType; }
private Cecil.TypeDefinition CreateDelegateDefinition(AnalysisNet.Types.TypeDefinition typeDefinition) { Cecil.TypeDefinition definition = CreateClassDefinition(typeDefinition); definition.IsSealed = true; return(definition); }