Пример #1
0
 // Utility methods (safe casts)
 public static MethodDefinition Method(object obj, AdviceSpec spec) {
     MethodDefinition result = obj as MethodDefinition;
     if (result == null)
         throw new AdviceException
             ("Expected a method, but got " + obj + ":" + obj.GetType(), spec);
     return result;
 }
Пример #2
0
 public override void Execute(AdviceSpec spec)
 {
     Console.WriteLine("ok:" + Cil.AspectsNavigator.Select("//*[match('* *::ShouldBeAvoided(*)')]").Count);
     Console.WriteLine("ok:" + spec.TargetNavigators.Count);
     foreach (Navigator targetNav in spec.TargetNavigators)
         throw new ForbiddenByAspect(targetNav.ToString(), spec);
 }
Пример #3
0
 public static Instruction Instruction(Navigator nav, AdviceSpec spec) {
     Instruction result = nav.Current as Instruction;
     if (result == null)
         throw new AdviceException
             ("Expected an instruction, but got " + nav.Current + ":" + nav.Current.GetType(), spec);
     return result;
 }
Пример #4
0
 public static TypeDefinition TypeDefinition(Navigator nav, AdviceSpec spec) {
     TypeDefinition result = nav.Current as TypeDefinition;
     if (result == null)
         throw new AdviceException
             ("Expected a type definition, but got " + nav.Current + " : " + nav.Current.GetType(), spec);
     return result;
 }
Пример #5
0
 public static Instruction CallInstruction(Navigator nav, AdviceSpec spec) {
     Instruction result = Instruction(nav, spec);
     string name = result.OpCode.Name;
     if (!name.StartsWith("call") && !name.StartsWith("newobj"))
         throw new AdviceException("Expected a call instruction, but got " + nav.Current, spec);
     return result;
 }
Пример #6
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);
                        }  
                    }
                }
            }
        }
Пример #7
0
 public static MethodDefinition ConcreteMethod(Navigator nav, AdviceSpec spec)
 {
     MethodDefinition result = Method(nav, spec);
     if (result.IsAbstract) throw new AdviceException
         ("Expected a concrete method, but got " + result, spec);
     return result;
 }
Пример #8
0
 public static TypeDefinition InterfaceDefinition(Navigator nav, AdviceSpec spec)
 {
     TypeDefinition result = TypeDefinition(nav, spec);
     if (!result.IsInterface) throw new AdviceException
        ("Expected an interface definition, but got " + nav.Current, spec);
     return result;
 }
Пример #9
0
 public void Execute(AdviceSpec spec)
 {
     foreach (Navigator targetNav in spec.TargetNavigators){
         TypeDefinition typeDef = Narrow.TypeDefinition(targetNav, spec);
         foreach(Navigator aspectNav in spec.AspectNavigators)
             typeDef.Interfaces.Add(Cil.TargetMainModule.Import(Narrow.InterfaceDefinition(aspectNav, spec)));
     }
 }
Пример #10
0
 public static MethodDefinition ConcreteMethodMatching(Navigator nav, string regex, AdviceSpec spec) {
     MethodDefinition result = Method(nav, spec);
     if (!SimpleRegex.IsMatch(result, regex)) {
         string errorMsg = string.Format
             ("Expected to match signature {0}, but got {1}",
             SimpleRegex.EscapePseudoRegex(regex), result);
         throw new AdviceException(errorMsg, spec);
     }
     return result;
 }
        public static AdviceSpec Create(Decorator d)
        {
            AdviceSpec spec = (AdviceSpec)Activator.CreateInstance(Type.GetType(m_Namespace + d.Name));

            spec.aspectRegExp = d["@aspectRegExp"];
            spec.targetRegExp = d["@targetRegExp"];
            spec.aspectXPath  = d["@aspectXPath"];
            spec.targetXPath  = d["@targetXPath"];
            return(spec);
        }
Пример #12
0
 public void Execute(AdviceSpec spec)
 {
     // meta-aspect attributes/xml elements have the same name as the meta-aspect type
     MetaAspect meta = m_MetaAspects[spec.GetType().Name] as MetaAspect;
     if (meta == null) throw new AdviceException("This spec isn't supported", spec);
     else {
         Eval(spec, meta.XPathBase, meta.XPathConstraint);
         meta.Execute(spec);
         Log.LogExecutedSpec(spec);
         if (!m_NeedCleanup.Contains(meta)) m_NeedCleanup.Add(meta);
     }
 }
Пример #13
0
		public AdviceException(string message, AdviceSpec spec) : base(message) {
			Spec = spec;
		}
Пример #14
0
 public static MethodDefinition StaticMethodMatching(Navigator nav, string regex, AdviceSpec spec)
 {
     MethodDefinition result = ConcreteMethodMatching(nav, regex, spec);
     if (!result.IsStatic) throw new AdviceException
        ("Expected a method, but got " + result, spec);
     return result;
 }
Пример #15
0
 public static MethodDefinition Method(Navigator nav, AdviceSpec spec)
 {
     return Method((object)nav.Current, spec);
 }
Пример #16
0
 public void AddAdvice(AdviceSpec spec, string origin)
 {
     spec.origin = origin;
     Advice.Add(spec);
 }
Пример #17
0
 public static MethodDefinition Interceptor(Navigator nav, AdviceSpec spec)
 {
     return StaticMethodMatching(nav,
         "System.Object *::*(DotNetGuru.AspectDNG.Joinpoints.*)", spec);
 }
Пример #18
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);
            }
        }
Пример #19
0
        public void Execute(AdviceSpec spec)
        {
            foreach (Navigator aspectNav in spec.AspectNavigators) {
                IMethodDefinition aspectMethod = Narrow.Interceptor(aspectNav, spec);
                foreach (Navigator targetNav in spec.TargetNavigators) {
                    MethodDefinition targetMethod = Narrow.ConcreteMethod(targetNav, spec);

                    // Prevent recursive weaving
                    if (targetMethod != aspectMethod &&
                        ! Cil.BelongsToAspectDng(targetMethod) &&
                        ! Cil.BelongsToAspectDng(aspectMethod) &&
                        targetMethod.GenericParameters.Count == 0 &&
                        targetMethod.DeclaringType.GenericParameters.Count == 0)

                        // Cannot keep semantics of "ref" parameters
                        if (targetMethod.ToString().IndexOf("&") == -1)
                            AddInterceptor(targetMethod, aspectMethod);
                }
            }
        }
Пример #20
0
        // MetaAspect Eval
        /// Some definitions may have been added from outside (typically for embedded advice)
        /// Just add the new definitions the expressions point to
        private void Eval(AdviceSpec spec, string XPathBase, string XPathConstraint)
        {
            // Evaluate the XPath expressions on Cecil object model
            if (spec.targetXPath != null)
                spec.TargetNavigators.AddRange(Cil.TargetNavigator.SelectList(spec.targetXPath + XPathConstraint));
            else if (spec.targetRegExp != null)
                foreach (Navigator nav in Cil.TargetNavigator.SelectList(XPathBase + XPathConstraint))
                    if (SimpleRegex.IsPreciseMatch(nav, spec.targetRegExp))
                        spec.TargetNavigators.Add(nav);

            if (spec.aspectXPath != null)
                spec.AspectNavigators.AddRange(Cil.AspectsNavigator.SelectList(spec.aspectXPath));
            else if (spec.aspectRegExp != null)
                foreach (Navigator nav in Cil.AspectsNavigator.SelectList(Cil.AllDeclarations))
                    if (SimpleRegex.IsPreciseMatch(nav, spec.aspectRegExp))
                        spec.AspectNavigators.Add(nav);
        }
Пример #21
0
 public void Execute(AdviceSpec spec)
 {
     foreach (Navigator targetNav in spec.TargetNavigators)
         foreach (Navigator aspectNav in spec.AspectNavigators)
             Cil.CopyTo(targetNav.Current, (ICloneable)aspectNav.Current);
 }
Пример #22
0
        public void Execute(AdviceSpec spec)
        {
            if (spec.AspectNavigators.Count != 1)
                throw new AdviceException("One and only one base type can be set to a target type, but got " + spec.AspectNavigators.Count, spec);

            TypeDefinition parentTypeDef = Narrow.TypeDefinition((Navigator)spec.AspectNavigators[0], spec);

            foreach (Navigator targetNav in spec.TargetNavigators)
                Narrow.TypeDefinition(targetNav, spec).BaseType = Cil.TargetMainModule.Import(parentTypeDef);
        }
Пример #23
0
 public virtual void Execute(AdviceSpec spec)
 {
     foreach (Navigator targetNav in spec.TargetNavigators)
         Log.LogWarning(targetNav.Current);
 }
Пример #24
0
 public static void LogExecutedSpec(AdviceSpec spec)
 {
     m_ExecutedSpecs.Add(spec);
 }
Пример #25
0
        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);
                }
            }
        }
Пример #26
0
		public AdviceException(string message, AdviceSpec spec, Exception rootCause) : base(message, rootCause) {
			Spec = spec;
		}
Пример #27
0
        public AspectDngConfig(string configFile)
        {
            m_Instance = this;

            try{
                Decorator conf = new Decorator(configFile);
                conf.GoTo("/AspectDngConfig");

                // Read variables from the main config file
                foreach (Decorator d in conf.GetDecorators("//Variable"))
                {
                    Variables[d["@name"]] = d["@value"];
                }

                debug    = bool.Parse(conf["@debug"]);
                warnings = DereferenceVariablesIn(conf["@warnings"]);
                weaving  = DereferenceVariablesIn(conf["@weaving"]);

                AspectsAssembly = DereferenceVariablesIn(conf["AspectsAssembly"]);
                TargetAssembly  = DereferenceVariablesIn(conf["TargetAssembly"]);
                WeavedAssembly  = DereferenceVariablesIn(conf["WeavedAssembly"]);

                PrivateLocations = conf.GetStrings("//PrivatePath");

                foreach (Decorator d in conf.GetDecorators("//Advice/*[not(self::Variable)]"))
                {
                    AdviceSpec spec = AdviceSpec.Create(d);
                    spec.DereferenceVariables();
                    AddAdvice(spec, configFile);
                }

                foreach (string path in conf.GetStrings("//AdviceFile"))
                {
                    Decorator otherConf = new Decorator(DereferenceVariablesIn(path));
                    foreach (Decorator otherD in otherConf.GetDecorators("//Advice/*[not(self::Variable)]"))
                    {
                        AdviceSpec spec = AdviceSpec.Create(otherD);
                        spec.DereferenceVariables();
                        AddAdvice(spec, path);
                    }
                    foreach (Decorator otherD in otherConf.GetDecorators("//Variable"))
                    {
                        Variables[otherD["@name"]] = otherD["@value"];
                    }
                }

                Log.Level = debug ? LogLevel.Debug : LogLevel.Warn;
            }
            catch (Exception e) {
                if (e.GetType().FullName.StartsWith("System.Xml"))
                {
                    throw new ConfigurationException(e);
                }
                else
                {
                    throw e;
                }
            }

            foreach (AdviceSpec spec in Advice)
            {
                spec.origin = configFile;
            }
            Environment.CurrentDirectory = new FileInfo(configFile).Directory.FullName;
            m_Instance = this;
        }
Пример #28
0
		public ForbiddenByAspect(string message, AdviceSpec spec) 
			: base("This usage if forbidden by an aspect:\n\t" + message, spec){}
Пример #29
0
 public void AddAdvice(AdviceSpec spec, string origin)
 {
     spec.origin = origin;
     Advice.Add(spec);
 }
Пример #30
0
 public void Execute(AdviceSpec spec)
 {
     foreach (Navigator targetNav in spec.TargetNavigators)
         targetNav.Remove();
 }
Пример #31
0
 public void Execute(AdviceSpec spec)
 {
     foreach (Navigator targetNav in spec.TargetNavigators)
         Narrow.TypeDefinition(targetNav, spec).Attributes |= TypeAttributes.Serializable;
 }