private IReadOnlyCollection <AdviceEffectBase> Extract(MethodDefinition method) { var advices = new List <AdviceEffectBase>(); foreach (var ca in method.CustomAttributes.ToList()) { if (ca.AttributeType.FullName == WellKnownTypes.Advice) { var adviceType = ca.GetConstructorValue <Broker.Advice.Type>(0); var advice = CreateEffect(adviceType); if (advice == null) { _weaver.LogError($"Unknown advice type {adviceType.ToString()}"); continue; } advice.Method = method; advice.Target = ca.GetConstructorValue <Target>(1); advice.Arguments = ExtractArguments(method); advices.Add(advice); } } return(advices); }
public bool Validate(BaseModuleWeaver weaver) { if (!Effects.Any()) { weaver.LogWarning($"Type {Host.FullName} has defined as an aspect, but lacks any effect."); } if (Host.HasGenericParameters) { weaver.LogError($"Aspect {Host.FullName} should not have generic parameters."); return(false); } if (Host.IsAbstract) { weaver.LogError($"Aspect {Host.FullName} cannot be static nor abstract."); return(false); } if (GetFactoryMethod() == null) { if (Factory != null) { weaver.LogError($"Type {Factory.FullName} should have 'public static object GetInstance(Type)' method in order to be aspect factory."); } else { weaver.LogError($"Aspect {Host.FullName} has no parameterless public constructor nor valid factory."); } return(false); } return(Effects.All(e => e.Validate(this, weaver))); }
public override bool Validate(AspectDefinition aspect, BaseModuleWeaver weaver) { if (!InterfaceType.Resolve().IsInterface) { weaver.LogError($"{InterfaceType.FullName} is not an interface."); return(false); } if (!aspect.Host.Implements(InterfaceType)) { weaver.LogError($"{aspect.Host.FullName} should implement {InterfaceType.FullName}."); return(false); } return(true); }
public AspectDefinition Read(TypeDefinition type) { if (!_cache.TryGetValue(type, out var aspectDef)) { var effects = ExtractEffects(type).ToList(); var aspect = ExtractAspectAttribute(type); if (aspect != null) { aspectDef = new AspectDefinition { Host = type, Scope = aspect.GetConstructorValue <Aspect.Scope>(0), Factory = aspect.GetPropertyValue <Aspect>(au => au.Factory) as TypeReference, Effects = effects } } ; else if (effects.Any()) { _weaver.LogError($"Type {type.FullName} has effects, but is not marked as an aspect. Concider using [Aspect] attribute."); } _cache.AddOrUpdate(type, aspectDef, (k, o) => aspectDef); } return(aspectDef); }
protected void LoadAdviceArgs(PointCut pc) { foreach (var arg in _effect.Arguments.OrderBy(a => a.Parameter.Index)) { switch (arg.Source) { case Source.Arguments: LoadArgumentsArgument(pc, arg); break; //case Source.Attributes: LoadAttributesArgument(pc, arg); break; case Source.Instance: LoadInstanceArgument(pc, arg); break; case Source.Method: LoadMethodArgument(pc, arg); break; case Source.Name: LoadNameArgument(pc, arg); break; case Source.ReturnType: LoadReturnTypeArgument(pc, arg); break; case Source.ReturnValue: LoadReturnValueArgument(pc, arg); break; case Source.Target: LoadTargetArgument(pc, arg); break; case Source.Type: LoadTypeArgument(pc, arg); break; default: _weaver.LogError($"Unknown argument source {arg.Source.ToString()}"); break; } } }
public void Weave(Injection injection) { var effect = (AdviceEffectBase)injection.Effect; if (injection.Target is EventDefinition) { var target = (EventDefinition)injection.Target; if (target.AddMethod != null && effect.Target.HasFlag(Target.EventAdd)) { WeaveMethod(target.AddMethod, injection); } if (target.RemoveMethod != null && effect.Target.HasFlag(Target.EventRemove)) { WeaveMethod(target.RemoveMethod, injection); } return; } if (injection.Target is PropertyDefinition) { var target = (PropertyDefinition)injection.Target; if (target.SetMethod != null && effect.Target.HasFlag(Target.Setter)) { WeaveMethod(target.SetMethod, injection); } if (target.GetMethod != null && effect.Target.HasFlag(Target.Getter)) { WeaveMethod(target.GetMethod, injection); } return; } if (injection.Target is MethodDefinition) { var target = (MethodDefinition)injection.Target; if (target.IsConstructor && effect.Target.HasFlag(Target.Constructor)) { WeaveMethod(target, injection); } if (target.IsNormalMethod() && effect.Target.HasFlag(Target.Method)) { WeaveMethod(target, injection); } return; } _weaver.LogError($"Unsupported target {injection.Target.GetType().Name}"); }
public static void CheckForBadAttributes(BaseModuleWeaver Weaver, List <TypeDefinition> types) { foreach (var typeDefinition in types) { foreach (var method in typeDefinition.AbstractMethods()) { if (method.ContainsAttribute(WeaveHelper.CacheAttributeName)) { Weaver.LogError($"Method '{method.FullName}' is abstract but has a [CacheAttribute]. Remove this attribute."); } } } }
public override bool Validate(AspectDefinition aspect, BaseModuleWeaver weaver) { if (Method.IsStatic) { weaver.LogError($"Advice {Method.FullName} cannot be static."); return(false); } if (!Method.IsPublic) { weaver.LogError($"Advice {Method.FullName} should be public."); return(false); } if (Method.ReturnType != Method.Module.TypeSystem.Void) { weaver.LogError($"Advice {Method.FullName} should be void."); return(false); } return(true); }
private IEnumerable <Injection> ParseInjectionAttribute(ICustomAttributeProvider target, CustomAttribute attr) { var aspectRef = attr.GetConstructorValue <TypeReference>(0); var aspect = _aspectReader.Read(aspectRef.Resolve()); if (aspect == null) { _weaver.LogError($"Type {aspectRef.FullName} should be an aspect class."); return(Enumerable.Empty <Injection>()); } ushort priority = /* attr.GetPropertyValue<Broker.Inject, ushort>(i => i.Priority)*/ 0; // var childFilter = attr.GetPropertyValue<Broker.Inject, InjectionChildFilter>(i => i.Filter); var injections = FindApplicableMembers(target, aspect, priority /*, childFilter*/); return(injections); }
public void ProcessModule(ModuleDefinition module, bool optimize) { var aspects = _aspectExtractor.ReadAll(module); _weaver.LogInfo($"Found {aspects.Count} aspects"); var injections = _injectionCollector.ReadAll(module).ToList(); _weaver.LogInfo($"Found {injections.Count} injections"); if (aspects.Count != 0) { _weaver.LogInfo($"Processing aspects..."); foreach (var aspect in aspects) { _aspectWeaver.WeaveGlobalAssests(aspect); } } if (injections.Count != 0) { _weaver.LogInfo($"Processing injections..."); foreach (var injector in _effectWeavers.OrderByDescending(i => i.Priority)) { _weaver.LogInfo($"Executing {injector.GetType().Name}..."); foreach (var prioritizedInjections in injections.GroupBy(i => i.Priority).OrderByDescending(a => a.Key).ToList()) { foreach (var injection in prioritizedInjections.OrderByDescending(i => i.Effect.Priority)) { if (injector.CanWeave(injection)) { injector.Weave(injection); injections.Remove(injection); } } } } foreach (var injection in injections) { _weaver.LogError($"Couldn't find weaver for {injection}"); } } if (optimize) { _weaver.LogInfo($"Cleanup and optimize..."); } else { _weaver.LogInfo($"Cleanup..."); } if (optimize) { EditorFactory.Optimize(module); } EditorFactory.CleanUp(module); }