public static VTable GetVTable(NameAnalyzer analyzer, TypeDefinition typeDef, Dictionary <TypeDefinition, VTable> tbls) { if (tbls.ContainsKey(typeDef)) { return(tbls[typeDef]); } //Partition II 10.3, 12.2 VTable ret = new VTable() { TypeDef = typeDef }; TypeDefinition baseType = null; if (typeDef.BaseType != null) { baseType = typeDef.BaseType.Resolve(); if (baseType != null) { ret.Table = new List <VTableSlot>(GetVTable(analyzer, baseType, tbls).Table); if (typeDef.BaseType is GenericInstanceType) { GenericInstanceType genInst = typeDef.BaseType as GenericInstanceType; for (int i = 0; i < ret.Table.Count; i++) { ret.Table[i] = ret.Table[i].Clone(); ret.Table[i].OpenCurrent = ret.Table[i].Current; ret.Table[i].Current = Resolve(ret.Table[i].OpenCurrent, genInst); ret.Table[i].OpenRoot = ret.Table[i].Root; ret.Table[i].Root = Resolve(ret.Table[i].OpenRoot, genInst); } } } else { ret.Table = new List <VTableSlot>(); } } else { ret.Table = new List <VTableSlot>(); } if (typeDef.HasInterfaces) //Interface methods { foreach (var i in typeDef.Interfaces) { if (baseType != null && baseType.Interfaces.Contains(i)) { continue; } TypeDefinition iface = i.Resolve(); if (iface == null) { continue; } GenericInstanceType genInst = i as GenericInstanceType; foreach (var j in iface.Methods) { MethodReference ifaceMethod = j; if (genInst != null) { ifaceMethod = Resolve(ifaceMethod, genInst); } VTableSlot slot = null; for (int k = 0; k < ret.Table.Count; k++) { if (Match(ifaceMethod, ret.Table[k].Root)) { slot = ret.Table[k]; break; } } if (slot == null) { if (genInst != null) { ret.Table.Add(new VTableSlot() { Root = ifaceMethod, OpenRoot = j, Current = null }); } else { ret.Table.Add(new VTableSlot() { Root = ifaceMethod, Current = null }); } } else { slot.ReplaceRoot(analyzer, j); } } } } foreach (var i in typeDef.Methods) //Interface virtual newslot { if (!i.IsVirtual || !i.IsNewSlot) { continue; } for (int j = 0; j < ret.Table.Count; j++) { if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root)) { ret.Table[j].ReplaceCurrent(analyzer, i); } } } foreach (var i in typeDef.Methods) //Interface virtual { if (!i.IsVirtual) { continue; } for (int j = 0; j < ret.Table.Count; j++) { if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root)) { ret.Table[j].ReplaceCurrent(analyzer, i); } } } foreach (var i in typeDef.Methods) //Base newslot { if (!i.IsVirtual || !i.IsNewSlot) { continue; } for (int j = 0; j < ret.Table.Count; j++) { if (Match(i, ret.Table[j].Current)) { ret.Table[j].Root = i; ret.Table[j].ReplaceCurrent(analyzer, i); } } } foreach (var i in typeDef.Methods) //Base virtual { if (!i.IsVirtual) { continue; } for (int j = 0; j < ret.Table.Count; j++) { if (i != ret.Table[j].Current && Match(i, ret.Table[j].Current)) { ret.Table[j].ReplaceCurrent(analyzer, i); } } } foreach (var i in typeDef.Methods) //Remaining { if (!i.IsVirtual) { continue; } bool matched = false; for (int j = 0; j < ret.Table.Count; j++) { if (Match(i, ret.Table[j].Current)) { matched = true; break; } } if (!matched) { ret.Table.Add(new VTableSlot() { Root = i, Current = i }); } } tbls[typeDef] = ret; return(ret); }
public static VTable GetVTable(NameAnalyzer analyzer, TypeDefinition typeDef, Dictionary<TypeDefinition, VTable> tbls) { if (tbls.ContainsKey(typeDef)) return tbls[typeDef]; //Partition II 10.3, 12.2 VTable ret = new VTable() { TypeDef = typeDef }; TypeDefinition baseType = null; if (typeDef.BaseType != null) { baseType = typeDef.BaseType.Resolve(); if (baseType != null) { ret.Table = new List<VTableSlot>(GetVTable(analyzer, baseType, tbls).Table); if (typeDef.BaseType is GenericInstanceType) { GenericInstanceType genInst = typeDef.BaseType as GenericInstanceType; for (int i = 0; i < ret.Table.Count; i++) { ret.Table[i] = ret.Table[i].Clone(); ret.Table[i].OpenCurrent = ret.Table[i].Current; ret.Table[i].Current = Resolve(ret.Table[i].OpenCurrent, genInst); ret.Table[i].OpenRoot = ret.Table[i].Root; ret.Table[i].Root = Resolve(ret.Table[i].OpenRoot, genInst); } } } else ret.Table = new List<VTableSlot>(); } else ret.Table = new List<VTableSlot>(); if (typeDef.HasInterfaces) //Interface methods { foreach (var i in typeDef.Interfaces) { if (baseType != null && baseType.Interfaces.Contains(i)) continue; TypeDefinition iface = i.Resolve(); if (iface == null) continue; GenericInstanceType genInst = i as GenericInstanceType; foreach (var j in iface.Methods) { MethodReference ifaceMethod = j; if (genInst != null) ifaceMethod = Resolve(ifaceMethod, genInst); VTableSlot slot = null; for (int k = 0; k < ret.Table.Count; k++) if (Match(ifaceMethod, ret.Table[k].Root)) { slot = ret.Table[k]; break; } if (slot == null) { if (genInst != null) ret.Table.Add(new VTableSlot() { Root = ifaceMethod, OpenRoot = j, Current = null }); else ret.Table.Add(new VTableSlot() { Root = ifaceMethod, Current = null }); } else { slot.ReplaceRoot(analyzer, j); } } } } foreach (var i in typeDef.Methods) //Interface virtual newslot { if (!i.IsVirtual || !i.IsNewSlot) continue; for (int j = 0; j < ret.Table.Count; j++) if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root)) ret.Table[j].ReplaceCurrent(analyzer, i); } foreach (var i in typeDef.Methods) //Interface virtual { if (!i.IsVirtual) continue; for (int j = 0; j < ret.Table.Count; j++) if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root)) ret.Table[j].ReplaceCurrent(analyzer, i); } foreach (var i in typeDef.Methods) //Base newslot { if (!i.IsVirtual || !i.IsNewSlot) continue; for (int j = 0; j < ret.Table.Count; j++) if (Match(i, ret.Table[j].Current)) { ret.Table[j].Root = i; ret.Table[j].ReplaceCurrent(analyzer, i); } } foreach (var i in typeDef.Methods) //Base virtual { if (!i.IsVirtual) continue; for (int j = 0; j < ret.Table.Count; j++) if (i != ret.Table[j].Current && Match(i, ret.Table[j].Current)) { ret.Table[j].ReplaceCurrent(analyzer, i); } } foreach (var i in typeDef.Methods) //Remaining { if (!i.IsVirtual) continue; bool matched = false; for (int j = 0; j < ret.Table.Count; j++) if (Match(i, ret.Table[j].Current)) { matched = true; break; } if (!matched) ret.Table.Add(new VTableSlot() { Root = i, Current = i }); } tbls[typeDef] = ret; return ret; }