private ImportedMember ImportMember(MemberReference mref) { if (mref == null) { return(null); } if (mref is GenericInstanceMethod) { GenericInstanceMethod gm = (GenericInstanceMethod)mref; for (int i = 0; i < gm.GenericArguments.Count; i++) { ImportType(gm.GenericArguments[i]); } mref = gm.ElementMethod; } if (mref is MethodDefinition) { return(null); } if (memberCache.ContainsKey(mref)) { return(memberCache[mref]); } ImportedType it = ImportType(mref.DeclaringType); if (it == null) { return(null); } ImportedMember mb = new ImportedMember(); it.members.Add(mb); mb.name = mref.Name; if (mref is FieldReference) { mb.signature = ((FieldReference)mref).Resolve().FullName; mb.kind = ElementType.field; } else { mb.signature = ((MethodReference)mref).Resolve().FullName; mb.kind = ElementType.method; } mb.kindSpecified = true; memberCache.Add(mref, mb); return(mb); }
private void ImplementType(TypeReference tref) { if (tref is TypeDefinition) { return; } if (tref is GenericInstanceType) { GenericInstanceType gt = (GenericInstanceType)tref; for (int i = 0; i < gt.GenericArguments.Count; i++) { ImportType(gt.GenericArguments[i]); } if (gt.ElementType is TypeDefinition) { return; } } ImportedType it = ImportType(tref); if (it != null) { if (it.implementedByType) { return; // already done } it.implementedByType = true; it.implementedByTypeSpecified = true; it.implemented = new List <ImplementedMember>(); TypeDefinition type = tref.Resolve(); foreach (var el in type.Methods) // at this point we have to presume the current class implements them all { ImplementedMember im = new ImplementedMember(); im.name = el.Name; im.signature = el.FullName; it.implemented.Add(im); } } }
private void ImplementMember(MethodReference mref) { if (mref is MethodDefinition) { return; } ImportedType it = ImportType(mref.DeclaringType); if (it == null) { return; // nothing to do here } if (it.implemented == null) { it.implemented = new List <ImplementedMember>(); } it.implemented.Add(new ImplementedMember { name = mref.Name, signature = mref.FullName }); }
private static bool CheckType(AssemblyDefinition ad, ImportedType type) { TypeDefinition td = null; string name = type.name; if (name.Contains("/")) { name = name.Substring(0, name.IndexOf("/")); td = ad.Modules.SelectMany(a => a.Types).FirstOrDefault(a => a.FullName == name); foreach (var el in type.name.Substring(type.name.IndexOf("/") + 1).Split('/')) { if (td == null) break; td = td.NestedTypes.FirstOrDefault(a => a.Name == el); } } else td = ad.Modules.SelectMany(a => a.Types).FirstOrDefault(a => a.FullName == name); if (td == null) { Log("Missing type: {0}", type.name); return false; } bool ok = true; if (td.IsInterface && type.implementedByTypeSpecified && type.implementedByType) { for (int i = 0; i < td.Methods.Count; i++) { if (!type.implemented.Any(a => a.signature == td.Methods[i].FullName)) { Log("Interface {0} has new interface member that did not exist before: {1}", type.name, td.Methods[i].FullName); ok = false; } } } else if (type.implemented.Count > 0) // overrides { if (td.IsSealed || ! td.IsPublic) { ok = false; Log("Type is sealed or private while it should not be: {0}", type.name); } for (int i = 0; i < type.implemented.Count; i++) { if (!td.Methods.Any(a => a.FullName == type.implemented[i].signature)) { Log("Type {0} has a method that was overriden in a subclass but no longer exists: {1}", type.name, type.implemented[i].signature); ok = false; } } } for (int i = 0; i < type.members.Count; i++) { switch (type.members[i].kind) { case ElementType.field: if (!td.Fields.Any(a => a.FullName == type.members[i].signature)) { ok = false; Log("Type {0} has a missing field: {1}", type.name, type.members[i].signature); } break; default: if (!td.Methods.Any(a => a.FullName == type.members[i].signature)) { ok = false; Log("Type {0} has a missing method: {1}", type.name, type.members[i].signature); } break; } } return ok; }
private ImportedType ImportType(TypeReference tref) { if (tref == null) { return(null); } switch (tref.MetadataType) { case MetadataType.Pointer: case MetadataType.Pinned: case MetadataType.Array: ImportType(tref.GetElementType()); return(null); case MetadataType.OptionalModifier: case MetadataType.RequiredModifier: case MetadataType.ByReference: return(ImportType(tref.GetElementType())); case MetadataType.Boolean: case MetadataType.Byte: case MetadataType.Char: case MetadataType.Double: case MetadataType.FunctionPointer: case MetadataType.GenericInstance: case MetadataType.Int16: case MetadataType.Int32: case MetadataType.Int64: case MetadataType.IntPtr: case MetadataType.MVar: case MetadataType.Object: case MetadataType.SByte: case MetadataType.Single: case MetadataType.String: case MetadataType.UInt16: case MetadataType.UInt32: case MetadataType.UInt64: case MetadataType.UIntPtr: case MetadataType.ValueType: case MetadataType.Var: case MetadataType.Void: case MetadataType.TypedByReference: return(null); } if (tref is GenericInstanceType) { GenericInstanceType gt = (GenericInstanceType)tref; for (int i = 0; i < gt.GenericArguments.Count; i++) { ImportType(gt.GenericArguments[i]); } if (gt.ElementType is TypeDefinition) { return(null); } tref = gt.ElementType; } if (tref is TypeDefinition) { return(null); } if (typeCache.ContainsKey(tref)) { return(typeCache[tref]); } if (Program.IsFiltered(tref)) { return(null); } var mod = output.library.Where(a => a.name == tref.Scope.Name).FirstOrDefault(); if (mod == null) { mod = new ImportedLibrary(); mod.name = tref.Scope.Name; mod.fullname = tref.Module.AssemblyReferences.Where(a => a.Name == tref.Scope.Name).FirstOrDefault().FullName; output.library.Add(mod); } var it = new ImportedType(); it.name = tref.ToString(); mod.type.Add(it); typeCache.Add(tref, it); return(it); }
private static bool CheckType(AssemblyDefinition ad, ImportedType type) { TypeDefinition td = null; string name = type.name; if (name.Contains("/")) { name = name.Substring(0, name.IndexOf("/")); td = ad.Modules.SelectMany(a => a.Types).FirstOrDefault(a => a.FullName == name); foreach (var el in type.name.Substring(type.name.IndexOf("/") + 1).Split('/')) { if (td == null) { break; } td = td.NestedTypes.FirstOrDefault(a => a.Name == el); } } else { td = ad.Modules.SelectMany(a => a.Types).FirstOrDefault(a => a.FullName == name); } if (td == null) { Log("Missing type: {0}", type.name); return(false); } bool ok = true; if (td.IsInterface && type.implementedByTypeSpecified && type.implementedByType) { for (int i = 0; i < td.Methods.Count; i++) { if (!type.implemented.Any(a => a.signature == td.Methods[i].FullName)) { Log("Interface {0} has new interface member that did not exist before: {1}", type.name, td.Methods[i].FullName); ok = false; } } } else if (type.implemented.Count > 0) // overrides { if (td.IsSealed || !td.IsPublic) { ok = false; Log("Type is sealed or private while it should not be: {0}", type.name); } for (int i = 0; i < type.implemented.Count; i++) { if (!td.Methods.Any(a => a.FullName == type.implemented[i].signature)) { Log("Type {0} has a method that was overriden in a subclass but no longer exists: {1}", type.name, type.implemented[i].signature); ok = false; } } } for (int i = 0; i < type.members.Count; i++) { switch (type.members[i].kind) { case ElementType.field: if (!td.Fields.Any(a => a.FullName == type.members[i].signature)) { ok = false; Log("Type {0} has a missing field: {1}", type.name, type.members[i].signature); } break; default: if (!td.Methods.Any(a => a.FullName == type.members[i].signature)) { ok = false; Log("Type {0} has a missing method: {1}", type.name, type.members[i].signature); } break; } } return(ok); }
private ImportedType ImportType(TypeReference tref) { if (tref == null) return null; switch (tref.MetadataType) { case MetadataType.Pointer: case MetadataType.Pinned: case MetadataType.Array: ImportType(tref.GetElementType()); return null; case MetadataType.OptionalModifier: case MetadataType.RequiredModifier: case MetadataType.ByReference: return ImportType(tref.GetElementType()); case MetadataType.Boolean: case MetadataType.Byte: case MetadataType.Char: case MetadataType.Double: case MetadataType.FunctionPointer: case MetadataType.GenericInstance: case MetadataType.Int16: case MetadataType.Int32: case MetadataType.Int64: case MetadataType.IntPtr: case MetadataType.MVar: case MetadataType.Object: case MetadataType.SByte: case MetadataType.Single: case MetadataType.String: case MetadataType.UInt16: case MetadataType.UInt32: case MetadataType.UInt64: case MetadataType.UIntPtr: case MetadataType.ValueType: case MetadataType.Var: case MetadataType.Void: case MetadataType.TypedByReference: return null; } if (tref is GenericInstanceType) { GenericInstanceType gt = (GenericInstanceType)tref; for (int i = 0; i < gt.GenericArguments.Count; i++) ImportType(gt.GenericArguments[i]); if (gt.ElementType is TypeDefinition) return null; tref = gt.ElementType; } if (tref is TypeDefinition) return null; if (typeCache.ContainsKey(tref)) return typeCache[tref]; if (Program.IsFiltered(tref)) return null; var mod = output.library.Where(a => a.name == tref.Scope.Name).FirstOrDefault(); if (mod == null) { mod = new ImportedLibrary(); mod.name = tref.Scope.Name; mod.fullname = tref.Module.AssemblyReferences.Where(a => a.Name == tref.Scope.Name).FirstOrDefault().FullName; output.library.Add(mod); } var it = new ImportedType(); it.name = tref.ToString(); mod.type.Add(it); typeCache.Add(tref, it); return it; }