// 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; }
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); }
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; }
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; }
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; }
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 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; }
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; }
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))); } }
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); }
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); } }
public AdviceException(string message, AdviceSpec spec) : base(message) { Spec = spec; }
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; }
public static MethodDefinition Method(Navigator nav, AdviceSpec spec) { return Method((object)nav.Current, spec); }
public void AddAdvice(AdviceSpec spec, string origin) { spec.origin = origin; Advice.Add(spec); }
public static MethodDefinition Interceptor(Navigator nav, AdviceSpec spec) { return StaticMethodMatching(nav, "System.Object *::*(DotNetGuru.AspectDNG.Joinpoints.*)", spec); }
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); } }
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); } } }
// 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); }
public void Execute(AdviceSpec spec) { foreach (Navigator targetNav in spec.TargetNavigators) foreach (Navigator aspectNav in spec.AspectNavigators) Cil.CopyTo(targetNav.Current, (ICloneable)aspectNav.Current); }
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); }
public virtual void Execute(AdviceSpec spec) { foreach (Navigator targetNav in spec.TargetNavigators) Log.LogWarning(targetNav.Current); }
public static void LogExecutedSpec(AdviceSpec spec) { m_ExecutedSpecs.Add(spec); }
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); } } }
public AdviceException(string message, AdviceSpec spec, Exception rootCause) : base(message, rootCause) { Spec = spec; }
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; }
public ForbiddenByAspect(string message, AdviceSpec spec) : base("This usage if forbidden by an aspect:\n\t" + message, spec){}
public void Execute(AdviceSpec spec) { foreach (Navigator targetNav in spec.TargetNavigators) targetNav.Remove(); }
public void Execute(AdviceSpec spec) { foreach (Navigator targetNav in spec.TargetNavigators) Narrow.TypeDefinition(targetNav, spec).Attributes |= TypeAttributes.Serializable; }