Пример #1
0
        public void Execute(AdviceSpec spec)
        {
            foreach (Navigator aspectNav in spec.AspectNavigators)
            {
                IMethodDefinition aspectMethod = Narrow.Interceptor(aspectNav, spec);
                foreach (Navigator targetNav in spec.TargetNavigators)
                {
                    Instruction      targetCallInstruction = Narrow.CallInstruction(targetNav, spec);
                    MethodReference  targetMethod          = (MethodReference)targetCallInstruction.Operand;
                    MethodDefinition containerMethod       = Narrow.Method(targetNav.Parent, spec);

                    // Prevent recursive weaving
                    if (targetMethod != aspectMethod &&
                        containerMethod != aspectMethod &&
                        !Cil.BelongsToAspectDng(targetMethod) &&
                        !Cil.BelongsToAspectDng(aspectMethod) &&
                        !Cil.BelongsToAspectDng(containerMethod) &&
                        targetMethod.GenericParameters.Count == 0 &&
                        targetMethod.DeclaringType.GenericParameters.Count == 0)
                    {
                        // Cannot weave on acces to boxed arrays. Methods look like int32[0...,0...]::Get(int32, int32)
                        if (targetMethod.DeclaringType.Name.IndexOf("]") == -1 &&
                            targetMethod.ToString().IndexOf("&") == -1
                            // To prevent base.SameMethod() calls from child types, event if AroundBody already occurred
                            && Cil.GetOriginalMethodName(targetMethod) != Cil.GetOriginalMethodName(containerMethod)
                            )
                        {
                            AddInterceptor(targetCallInstruction, containerMethod, aspectMethod);
                        }
                    }
                }
            }
        }
        public void Execute(AdviceSpec spec)
        {
            foreach (Navigator aspectNav in spec.AspectNavigators)
            {
                MethodDefinition aspectMethod = Narrow.Interceptor(aspectNav, spec);
                foreach (Navigator targetNav in spec.TargetNavigators)
                {
                    Instruction      targetCallInstruction = Narrow.Instruction(targetNav, spec);
                    MethodDefinition targetMethod          = Narrow.Method(targetNav.Parent, spec);

                    // We don't want to intercept volatile field accessors (marshalling problem)
                    string fieldTypeName = ((FieldReference)targetCallInstruction.Operand).FieldType.Name;
                    if (fieldTypeName.IndexOf(typeof(System.Runtime.CompilerServices.IsVolatile).Name) == -1)
                    {
                        AddInterceptor(targetCallInstruction, targetMethod, aspectMethod);
                    }
                }
            }
        }
Пример #3
0
        public void Execute(AdviceSpec spec)
        {
            foreach (Navigator aspectNav in spec.AspectNavigators)
            {
                MethodDefinition aspectMetaMethod = Narrow.Method(aspectNav, spec);

                MethodInfo aspectMethod = Cil.Aspects.GetType(aspectMetaMethod.DeclaringType.FullName).
                                          GetMethod(aspectMetaMethod.Name);

                bool preconditions = aspectMethod.IsStatic &&
                                     aspectMethod.ReturnType.FullName == typeof(string).FullName &&
                                     aspectMethod.GetParameters().Length == 1 &&
                                     aspectMethod.GetParameters()[0].ParameterType.FullName == typeof(TypeDefinition).FullName;
                if (!preconditions)
                {
                    throw new AdviceException("Aspect method signature must match : \n" +
                                              "public static string YourMethod(Mono.Cecil.TypeDefinition td)", spec);
                }

                foreach (Navigator targetNav in spec.TargetNavigators)
                {
                    TypeDefinition targetType = Narrow.TypeDefinition(targetNav, spec);

                    // Only insert members on classes (not structs because fields MUST be initialized in the ctor, no field initializer)
                    preconditions = !targetType.FullName.StartsWith("<") &&
                                    !targetType.IsValueType &&
                                    !targetType.IsInterface &&
                                    !(targetType.BaseType != null && targetType.BaseType.Name == "Delegate");

                    if (preconditions)
                    {
                        string code = aspectMethod.Invoke(null, new object[] { targetType }) as string;

                        if (code != null)
                        {
                            string className = DynamicClassName + ++m_ClassIndex;
                            code = new StringBuilder("public class ").
                                   Append(className).Append(" { \n").
                                   Append(code).Append("\n}").ToString();

                            try {
                                // CodeDom
                                CompilerResults results     = m_Compiler.CompileAssemblyFromSource(m_CompilerParams, code);
                                TypeDefinition  dynamicType = AssemblyFactory.GetAssembly(results.PathToAssembly).
                                                              MainModule.Types[className];

                                // Copy every method and field from the dynamic type to the targetTypeDef
                                dynamicType = Cil.TargetMainModule.Inject(dynamicType);

                                foreach (MethodDefinition method in dynamicType.Methods)
                                {
                                    targetType.Methods.Add(method.Clone());
                                }

                                foreach (FieldDefinition field in dynamicType.Fields)
                                {
                                    targetType.Fields.Add(field.Clone());
                                }

                                if (File.Exists(m_Path))
                                {
                                    File.Delete(m_Path);
                                }
                            } catch (Exception e) {
                                Console.WriteLine("error " + e);
                            }
                        }
                    }
                }

                // Remove aspect method from target assembly
                TypeDefinition typeDef = (TypeDefinition)aspectMetaMethod.DeclaringType;
                typeDef.Methods.Remove(aspectMetaMethod);
            }
        }