Example #1
0
        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);
        }
Example #2
0
        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)));
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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;
                }
            }
        }
Example #6
0
        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}");
        }
Example #7
0
 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.");
             }
         }
     }
 }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }