public static bool KeepMethod(TypeDefinition type, MethodDefinition method, out TransportAction visibility) { bool hasAttribute = false; TransportAction vis = TransportAction.Public; if (method.Name == ".cctor") { hasAttribute = true; vis = TransportAction.Copy; foreach (var i in type.CustomAttributes) { if (i.AttributeType.FullName == "NetCore.ClearFieldsAttribute") { vis = TransportAction.MoveClear; break; } } } else { foreach (var i in method.CustomAttributes) { if (i.AttributeType.FullName == "NetCore.RemoteCallAttribute") { hasAttribute = true; break; } if (i.AttributeType.FullName == "NetCore.RemoteMoveAttribute") { hasAttribute = true; vis = TransportAction.Move; break; } if (i.AttributeType.FullName == "NetCore.RemoteCopyAttribute") { hasAttribute = true; vis = TransportAction.Copy; break; } } } visibility = vis; return(hasAttribute); }
private static void PopulateDatas(ModuleDefinition mod, TypeDefinition type, Dictionary <MetadataToken, IMemberDefinition> mems) { TypeDefinition definition = mems[type.MetadataToken] as TypeDefinition; if (type.BaseType != null) { definition.BaseType = ImportType(type.BaseType, mod, null, mems); } foreach (TypeDefinition definition2 in type.NestedTypes) { PopulateDatas(mod, definition2, mems); } foreach (FieldDefinition definition3 in type.Fields) { if (!definition3.IsLiteral) { (mems[definition3.MetadataToken] as FieldDefinition).FieldType = ImportType(definition3.FieldType, mod, null, mems); } } foreach (MethodDefinition definition4 in type.Methods) { TransportAction visible = TransportAction.Public; if (!TypeCheck.KeepMethod(type, definition4, out visible)) { continue; } MethodAttributes methodAtt = definition4.Attributes; if (visible == TransportAction.Public) { if (methodAtt.HasFlag(MethodAttributes.Private)) { methodAtt &= ~MethodAttributes.Private; } methodAtt |= MethodAttributes.Public; } definition4.Attributes = methodAtt; PopulateMethod(mod, definition4, mems[definition4.MetadataToken] as MethodDefinition, mems); } }
private static TypeDefinition _Inject(ModuleDefinition mod, TypeDefinition type, Dictionary <MetadataToken, IMemberDefinition> mems) { TypeAttributes att = type.Attributes; if (att.HasFlag(TypeAttributes.NotPublic)) { att &= ~TypeAttributes.NotPublic; } att |= TypeAttributes.Public; TypeDefinition definition = new TypeDefinition(type.Namespace, type.Name, att) { ClassSize = type.ClassSize, PackingSize = type.PackingSize }; if (type.BaseType != null) { definition.BaseType = mod.Import(type.BaseType); } mems.Add(type.MetadataToken, definition); foreach (TypeDefinition definition2 in type.NestedTypes) { TypeDefinition item = _Inject(mod, definition2, mems); definition.NestedTypes.Add(item); } foreach (FieldDefinition definition4 in type.Fields) { if (!definition4.IsLiteral) { FieldDefinition definition5 = new FieldDefinition(definition4.Name, definition4.Attributes, mod.TypeSystem.Void); mems.Add(definition4.MetadataToken, definition5); definition.Fields.Add(definition5); } } foreach (MethodDefinition definition6 in type.Methods) { TransportAction visible = TransportAction.Public; if (!TypeCheck.KeepMethod(type, definition6, out visible)) { continue; } MethodAttributes methodAtt = definition6.Attributes; if (visible == TransportAction.Public) { if (methodAtt.HasFlag(MethodAttributes.Private)) { methodAtt &= ~MethodAttributes.Private; } if (visible == TransportAction.Public) { methodAtt |= MethodAttributes.Public; } } MethodDefinition definition7 = new MethodDefinition(definition6.Name, methodAtt, definition6.ReturnType); mems.Add(definition6.MetadataToken, definition7); definition.Methods.Add(definition7); } return(definition); }
void DealWithType(TypeDefinition type) { TypeAttributes att = type.Attributes; if (att.HasFlag(TypeAttributes.NotPublic)) { att &= ~TypeAttributes.NotPublic; } att |= TypeAttributes.Public; TypeDefinition nTypeDef = CecilHelper.Inject(newModule.MainModule, type); if (type.CustomAttributes.Where(x => x.AttributeType.FullName == "System.CodeDom.Compiler.GeneratedCodeAttribute").Count() != 0)//type.Namespace.EndsWith(".My") { // newModule.MainModule.Types.Add(.DeclaringType); newModule.MainModule.Import(type); return; } bool add = false; List <MethodDefinition> RemoveMethods = new List <MethodDefinition>(); foreach (MethodDefinition method in type.Methods) { if (!method.HasBody) { continue; } if (!method.IsStatic) { continue; } TransportAction visibility = TransportAction.Public; if (!TypeCheck.KeepMethod(type, method, out visibility)) { continue; } if (!method.IsStatic) { MessageBox.Show("RemoteCall must be only used on static methods.\n: " + method.FullName); throw new Exception("Not static"); } add = true; if (visibility == TransportAction.Move) { RemoveMethods.Add(method); continue; } if (visibility == TransportAction.Copy) { continue; } method.Body.Instructions.Clear(); ILProcessor ilp = method.Body.GetILProcessor(); if (visibility == TransportAction.MoveClear) { ilp.Append(Instruction.Create(OpCodes.Ret)); continue; } ilp.Append(Instruction.Create(OpCodes.Ldstr, Hashing.SHA(string.Format("{0}.{1}", type.FullName, method.Name)))); if (method.Parameters.Count == 0) { ilp.Append(Instruction.Create(OpCodes.Ldc_I4_0)); ilp.Append(Instruction.Create(OpCodes.Newarr, objectReference)); } else { ilp.Append(Instruction.Create(OpCodes.Ldc_I4, method.Parameters.Count)); ilp.Append(Instruction.Create(OpCodes.Newarr, objectReference)); for (int i = 0; i < method.Parameters.Count; i++) { ilp.Append(Instruction.Create(OpCodes.Dup)); ilp.Append(Instruction.Create(OpCodes.Ldc_I4, i)); ilp.Append(Instruction.Create(OpCodes.Ldarg, method.Parameters[i])); ilp.Append(Instruction.Create(OpCodes.Box, method.Parameters[i].ParameterType)); ilp.Append(Instruction.Create(OpCodes.Stelem_Ref)); } } ilp.Append(Instruction.Create(OpCodes.Call, CreateRemoteCallRef)); ilp.Append(Instruction.Create(OpCodes.Unbox_Any, method.ReturnType)); ilp.Append(Instruction.Create(OpCodes.Ret)); } foreach (MethodDefinition md in RemoveMethods) { type.Methods.Remove(md); } if (add) { newModule.MainModule.Types.Add(nTypeDef); } }