private PointcutSelector CreateAdviceSelector(ReflectionNode node, WeavingContext context)
        {
            var adviceSelector          = new PointcutSelector();
            var excludeAdviceAttributes = node.CustomAttributes.Where(ca => ca.AttributeType.SafeEquivalent(context.ExcludeAdviceAttributeType));

            foreach (var excludeAdviceAttribute in excludeAdviceAttributes)
            {
                var rule = new PointcutSelectorRule();
                // full names wildcards
                if (excludeAdviceAttribute.ConstructorArguments.Count == 1)
                {
                    rule.Names.AddRange(GetStrings(excludeAdviceAttribute.ConstructorArguments[0].Value));
                }

                // then named properties
                foreach (var namedArgument in excludeAdviceAttribute.NamedArguments)
                {
                    // names (which should usually not happen)
                    if (namedArgument.Name == nameof(ExcludeAdvicesAttribute.AdvicesTypes))
                    {
                        rule.Names.AddRange(GetStrings(namedArgument.Value));
                    }
                }
                adviceSelector.ExcludeRules.Add(rule);
            }
            if (node.Parent != null)
            {
                adviceSelector = GetAdviceSelector(node.Parent, context) + adviceSelector;
            }
            return(adviceSelector);
        }
Beispiel #2
0
        /// <summary>
        /// Creates the marker definition.
        /// </summary>
        /// <param name="typeDefinition">The type definition.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private MarkerDefinition CreateMarkerDefinition(TypeDef typeDefinition, WeavingContext context)
        {
            var priorityAttributes = typeDefinition.CustomAttributes.Where(a => a.AttributeType.SafeEquivalent(context.PriorityAttributeType)).ToList();

            if (priorityAttributes.Count > 1)
            {
                Logging.WriteWarning("Advice {0} has more than one priority. Using the first found", typeDefinition.FullName);
            }

#if uneedednow
            int priority = 0;
            if (priorityAttributes.Count > 0)
            {
                var priorityAttribute = priorityAttributes[0];
                priority = (int)priorityAttribute.ConstructorArguments[0].Value;
                Logging.WriteDebug("Advice {0} has priority {1}", typeDefinition.FullName, priority);
            }
#endif

            var abstractTarget = typeDefinition.CustomAttributes.Any(a => a.AttributeType.SafeEquivalent(context.AbstractTargetAttributeType));
            if (abstractTarget)
            {
                Logging.WriteDebug("Advice {0} abstracts target", typeDefinition.FullName);
            }
            var markerDefinition = new MarkerDefinition(typeDefinition, abstractTarget);
            return(markerDefinition);
        }
        /// <summary>
        /// Weaves method with weaving advices <see cref="IWeavingAdvice"/>.
        /// </summary>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="context">The context.</param>
        private void RunWeavingAdvices(MarkedNode markedMethod, WeavingContext context)
        {
            var method     = markedMethod.Node.Method;
            var methodName = method.Name;

            // our special recipe, with weaving advices
            var weavingAdvicesMarkers      = GetAllMarkers(markedMethod.Node, context.WeavingAdviceInterfaceType, context).Select(t => t.Item2).ToArray();
            var typeDefinition             = markedMethod.Node.Method.DeclaringType;
            var initialType                = TypeLoader.GetType(typeDefinition);
            var weaverMethodWeavingContext = new WeaverMethodWeavingContext(typeDefinition, initialType, methodName, context, TypeResolver, Logging);

            foreach (var weavingAdviceMarker in weavingAdvicesMarkers)
            {
                Logging.WriteDebug("Weaving method '{0}' using weaving advice '{1}'", method.FullName, weavingAdviceMarker.Type.FullName);
                var weavingAdviceType = TypeLoader.GetType(weavingAdviceMarker.Type);
                var weavingAdvice     = (IWeavingAdvice)Activator.CreateInstance(weavingAdviceType);
                if (weavingAdvice is IMethodWeavingAdvice methodWeavingAdvice && !method.IsGetter && !method.IsSetter)
                {
                    methodWeavingAdvice.Advise(weaverMethodWeavingContext);
                }
            }
            if (weaverMethodWeavingContext.TargetMethodName != methodName)
            {
                method.Name = weaverMethodWeavingContext.TargetMethodName;
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="WeaverMethodWeavingContext" /> class.
 /// </summary>
 /// <param name="typeDefinition">The type definition (type being built).</param>
 /// <param name="type">The type (original type).</param>
 /// <param name="targetMethodName">Name of the target method.</param>
 /// <param name="context">The context.</param>
 /// <param name="typeResolver">The type resolver.</param>
 /// <param name="logging">The logging.</param>
 public WeaverMethodWeavingContext(TypeDef typeDefinition, Type type, string targetMethodName, WeavingContext context, TypeResolver typeResolver, ILogging logging)
     : base(type, targetMethodName)
 {
     _typeDefinition = typeDefinition;
     _context        = context;
     _typeResolver   = typeResolver;
     _logging        = logging;
 }
Beispiel #5
0
 private static IEnumerable <FieldDef> GetRemovableFields(MethodDef method, WeavingContext context)
 {
     return(from instruction in method.Body.Instructions
            let fieldReference = instruction.Operand as IField
                                 where fieldReference is not null && fieldReference.DeclaringType.SafeEquivalent(method.DeclaringType)
                                 let fieldDefinition = fieldReference.ResolveFieldDef()
                                                       where fieldDefinition.CustomAttributes.Any(a => a.AttributeType.SafeEquivalent(context.CompilerGeneratedAttributeType))
                                                       select fieldDefinition);
 }
        private PointcutSelector GetAdviceSelector(ReflectionNode node, WeavingContext context)
        {
            if (node.AdviceSelector != null)
            {
                return(node.AdviceSelector);
            }

            return(node.AdviceSelector = CreateAdviceSelector(node, context));
        }
 /// <summary>
 /// Gets the rules at given advice.
 /// </summary>
 /// <param name="adviceType">Type of the advice.</param>
 /// <param name="context">The context.</param>
 /// <returns></returns>
 private PointcutSelector GetPointcutSelector(TypeDef adviceType, WeavingContext context)
 {
     if (context.AdvicesRules.TryGetValue(adviceType, out var pointcutRules))
     {
         return(pointcutRules);
     }
     context.AdvicesRules[adviceType] = pointcutRules = CreatePointcutSelector(adviceType, context);
     return(pointcutRules);
 }
Beispiel #8
0
        /// <summary>
        /// Determines whether the <see cref="MarkedNode"/> is included by pointcut
        /// </summary>
        /// <param name="markedNode">The marked node.</param>
        /// <param name="context">The context.</param>
        /// <returns>
        ///   <c>true</c> if [is included by pointcut] [the specified marked node]; otherwise, <c>false</c>.
        /// </returns>
        private bool IsIncludedByPointcut(MarkedNode markedNode, WeavingContext context)
        {
            var isIncludedByPointcut = GetPointcutSelectors(markedNode, context).Any(s => s.Select(markedNode.Node.Method));

            if (!isIncludedByPointcut)
            {
                Logging.WriteDebug("Excluding method '{0}' according to pointcut rules", markedNode.Node.Method.FullName);
            }
            return(isIncludedByPointcut);
        }
        /// <summary>
        /// Creates the pointcut rules for a given advice.
        /// </summary>
        /// <param name="adviceTypeDef">The advice type definition.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector CreatePointcutSelector(TypeDef adviceTypeDef, WeavingContext context)
        {
            var pointcutSelector = new PointcutSelector();

            foreach (var customAttribute in adviceTypeDef.CustomAttributes)
            {
                pointcutSelector += CreatePointcutSelector(customAttribute, context);
            }
            return(pointcutSelector);
        }
        /// <summary>
        /// Gets the rules at given <see cref="MarkedNode"/>.
        /// </summary>
        /// <param name="markedNode">The marked node.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector GetPointcutSelector(MarkedNode markedNode, WeavingContext context)
        {
            var rules = PointcutSelector.EmptySelector;

            foreach (var markerDefinition in markedNode.Definitions)
            {
                rules += GetPointcutSelector(markerDefinition.Type, context);
            }
            return(rules);
        }
        /// <summary>
        /// Creates the pointcut rules for a given advice.
        /// </summary>
        /// <param name="adviceType">Type of the advice.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector CreatePointcutSelector(ITypeDefOrRef adviceType, WeavingContext context)
        {
            var adviceTypeDef = TypeResolver.Resolve(adviceType);
            var rules         = new PointcutSelector();

            foreach (var customAttribute in adviceTypeDef.CustomAttributes)
            {
                rules += CreatePointcutSelector(customAttribute, context);
            }
            return(rules);
        }
        private static void AddGeneratedAttribute(MethodDefUser innerMethod, WeavingContext context)
        {
            // does this happen? Not sure.
            if (context.ExecutionPointAttributeDefaultCtor == null)
            {
                return;
            }
            var generatedAttribute = new CustomAttribute(context.ExecutionPointAttributeDefaultCtor);

            innerMethod.CustomAttributes.Add(generatedAttribute);
        }
Beispiel #13
0
        /// <summary>
        /// Gets the marker definition.
        /// </summary>
        /// <param name="typeDefinition">The type definition.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private MarkerDefinition GetMarkerDefinition(TypeDef typeDefinition, WeavingContext context)
        {
            lock (_markerDefinitions)
            {
                if (_markerDefinitions.TryGetValue(typeDefinition, out var markerDefinition))
                {
                    return(markerDefinition);
                }

                markerDefinition = CreateMarkerDefinition(typeDefinition, context);
                _markerDefinitions[typeDefinition] = markerDefinition;
                return(markerDefinition);
            }
        }
        /// <summary>
        /// Writes the invocation call.
        /// </summary>
        /// <param name="instructions">The instructions.</param>
        /// <param name="context">The context.</param>
        /// <param name="arguments">The arguments.</param>
        /// <exception cref="InvalidOperationException">
        /// </exception>
        private void WriteProceedCall(Instructions instructions, WeavingContext context, params InvocationArgument[] arguments)
        {
            var proceedMethod = GetProceedMethod(arguments, instructions.Module, context);

            foreach (var argument in arguments)
            {
                if (argument.HasValue)
                {
                    argument.Emit(instructions);
                }
            }

            instructions.Emit(OpCodes.Call, proceedMethod);
        }
Beispiel #15
0
        /// <summary>
        /// Creates the pointcut rules for a given advice.
        /// </summary>
        /// <param name="adviceTypeDef">The advice type definition.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector CreatePointcutSelector(TypeDef adviceTypeDef, WeavingContext context)
        {
            var pointcutSelector = new PointcutSelector();

            foreach (var customAttribute in adviceTypeDef.CustomAttributes)
            {
                pointcutSelector += CreatePointcutSelector(customAttribute, context);
            }
            var baseType = adviceTypeDef.BaseType.ResolveTypeDef();

            if (baseType != null)
            {
                pointcutSelector += GetPointcutSelector(baseType, context);
            }
            return(pointcutSelector);
        }
Beispiel #16
0
        private WeavingContext CreateWeavingContext(ModuleDefMD moduleDefinition)
        {
            var context = new WeavingContext
            {
                CompilerGeneratedAttributeType     = moduleDefinition.Import(typeof(CompilerGeneratedAttribute)),
                PriorityAttributeType              = TypeResolver.Resolve(moduleDefinition, typeof(PriorityAttribute)),
                AbstractTargetAttributeType        = TypeResolver.Resolve(moduleDefinition, typeof(AbstractTargetAttribute)),
                AdviceInterfaceType                = TypeResolver.Resolve(moduleDefinition, typeof(IAdvice)),
                WeavingAdviceInterfaceType         = TypeResolver.Resolve(moduleDefinition, typeof(IWeavingAdvice)),
                ExecutionPointAttributeDefaultCtor = moduleDefinition.Import(TypeResolver.Resolve(moduleDefinition, typeof(ExecutionPointAttribute)).FindDefaultConstructor()),
                ExcludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(ExcludePointcutAttribute)),
                IncludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(IncludePointcutAttribute)),
                ExcludeAdviceAttributeType         = TypeResolver.Resolve(moduleDefinition, typeof(ExcludeAdvicesAttribute)),
            };

            return(context);
        }
 private IMethod GetDefaultProceedMethod(ModuleDef module, WeavingContext context)
 {
     if (context.InvocationProceedMethod == null)
     {
         var invocationType = TypeResolver.Resolve(module, typeof(Invocation));
         if (invocationType == null)
         {
             throw new InvalidOperationException();
         }
         var proceedMethodReference = invocationType.Methods.SingleOrDefault(m => m.IsStatic && m.Name == nameof(Invocation.ProceedAdvice2));
         if (proceedMethodReference == null)
         {
             throw new InvalidOperationException();
         }
         context.InvocationProceedMethod = module.SafeImport(proceedMethodReference);
     }
     return(context.InvocationProceedMethod);
 }
Beispiel #18
0
        private WeavingContext CreateWeavingContext(ModuleDef moduleDefinition)
        {
            var context = new WeavingContext
            {
                CompilerGeneratedAttributeType     = moduleDefinition.Import(typeof(CompilerGeneratedAttribute)),
                PriorityAttributeType              = TypeResolver.Resolve(moduleDefinition, typeof(PriorityAttribute)),
                AbstractTargetAttributeType        = TypeResolver.Resolve(moduleDefinition, typeof(AbstractTargetAttribute)),
                AdviceInterfaceType                = TypeResolver.Resolve(moduleDefinition, typeof(IAdvice)),
                WeavingAdviceInterfaceType         = TypeResolver.Resolve(moduleDefinition, typeof(IWeavingAdvice)),
                ExecutionPointAttributeDefaultCtor = moduleDefinition.Import(TypeResolver.Resolve(moduleDefinition, typeof(ExecutionPointAttribute))?.FindDefaultConstructor()),
                ExcludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(ExcludePointcutAttribute)),
                IncludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(IncludePointcutAttribute)),
                ExcludeAdviceAttributeType         = TypeResolver.Resolve(moduleDefinition, typeof(ExcludeAdvicesAttribute)),
                IntroducedFieldType                = TypeResolver.Resolve(moduleDefinition, typeof(IntroducedField <>)),
                SharedIntroducedFieldType          = TypeResolver.Resolve(moduleDefinition, typeof(SharedIntroducedField <>)),
#pragma warning disable 618
                IntroducedFieldsType = TypeResolver.Resolve(moduleDefinition, typeof(IntroducedFieldsRegistry)),
#pragma warning restore 618
            };

            if (context.AdviceInterfaceType is not null)
            {
                if (context.ExecutionPointAttributeDefaultCtor is null)
                {
                    Logging.WriteError("ExecutionPointAttribute default ctor was not found");
                }

                if (context.ExcludePointcutAttributeType is null)
                {
                    Logging.WriteError("ExcludePointcutAttributeType was not found");
                }
                if (context.IncludePointcutAttributeType is null)
                {
                    Logging.WriteError("IncludePointcutAttributeType was not found");
                }
                if (context.ExcludeAdviceAttributeType is null)
                {
                    Logging.WriteError("ExcludeAdviceAttributeType was not found");
                }
            }

            return(context);
        }
        private PointcutSelector CreateAdviceSelector(ReflectionNode node, WeavingContext context)
        {
            var adviceSelector = new PointcutSelector();
            // Advices should not advise themselves
            var typeReflectionNode = node as TypeReflectionNode;

            if (typeReflectionNode != null && IsMarker(typeReflectionNode.TypeDefinition, context.AdviceInterfaceType))
            {
                Logging.WriteDebug("Excluding {0} from itself", typeReflectionNode.TypeDefinition.FullName);
                adviceSelector.ExcludeRules.Add(new PointcutSelectorRule(typeReflectionNode.TypeDefinition.FullName));
            }
            if (context.ExcludeAdviceAttributeType != null)
            {
                var excludeAdviceAttributes = node.CustomAttributes.Where(ca => ca.AttributeType.SafeEquivalent(context.ExcludeAdviceAttributeType));
                foreach (var excludeAdviceAttribute in excludeAdviceAttributes)
                {
                    var rule = new PointcutSelectorRule();
                    // full names wildcards
                    if (excludeAdviceAttribute.ConstructorArguments.Count == 1)
                    {
                        rule.Names.AddRange(GetStrings(excludeAdviceAttribute.ConstructorArguments[0].Value));
                    }

                    // then named properties
                    foreach (var namedArgument in excludeAdviceAttribute.NamedArguments)
                    {
                        // names (which should usually not happen)
                        if (namedArgument.Name == nameof(ExcludeAdvicesAttribute.AdvicesTypes))
                        {
                            rule.Names.AddRange(GetStrings(namedArgument.Value));
                        }
                    }
                    adviceSelector.ExcludeRules.Add(rule);
                }
            }
            if (node.Parent != null)
            {
                adviceSelector = GetAdviceSelector(node.Parent, context) + adviceSelector;
            }
            return(adviceSelector);
        }
Beispiel #20
0
        private WeavingContext CreateWeavingContext(ModuleDef moduleDefinition)
        {
            var context = new WeavingContext
            {
                CompilerGeneratedAttributeType     = moduleDefinition.Import(typeof(CompilerGeneratedAttribute)),
                PriorityAttributeType              = TypeResolver.Resolve(moduleDefinition, typeof(PriorityAttribute)),
                AbstractTargetAttributeType        = TypeResolver.Resolve(moduleDefinition, typeof(AbstractTargetAttribute)),
                AdviceInterfaceType                = TypeResolver.Resolve(moduleDefinition, typeof(IAdvice)),
                WeavingAdviceInterfaceType         = TypeResolver.Resolve(moduleDefinition, typeof(IWeavingAdvice)),
                ExecutionPointAttributeDefaultCtor = moduleDefinition.Import(TypeResolver.Resolve(moduleDefinition, typeof(ExecutionPointAttribute))?.FindDefaultConstructor()),
                ExcludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(ExcludePointcutAttribute)),
                IncludePointcutAttributeType       = TypeResolver.Resolve(moduleDefinition, typeof(IncludePointcutAttribute)),
                ExcludeAdviceAttributeType         = TypeResolver.Resolve(moduleDefinition, typeof(ExcludeAdvicesAttribute)),
            };

            if (context.AdviceInterfaceType != null)
            {
                if (context.ExecutionPointAttributeDefaultCtor == null)
                {
                    Logging.WriteError("ExecutionPointAttribute default ctor was not found");
                }

                if (context.ExcludePointcutAttributeType == null)
                {
                    Logging.WriteError("ExcludePointcutAttributeType was not found");
                }
                if (context.IncludePointcutAttributeType == null)
                {
                    Logging.WriteError("IncludePointcutAttributeType was not found");
                }
                if (context.ExcludeAdviceAttributeType == null)
                {
                    Logging.WriteError("ExcludeAdviceAttributeType was not found");
                }
            }

            return(context);
        }
Beispiel #21
0
        /// <summary>
        /// Gets the marked methods.
        /// </summary>
        /// <param name="reflectionNode">The reflection node.</param>
        /// <param name="markerInterface">The marker interface.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private IEnumerable <MarkedNode> GetMarkedMethods(ReflectionNode reflectionNode, ITypeDefOrRef markerInterface, WeavingContext context)
        {
            var ancestorsToChildren = reflectionNode.GetAncestorsToDescendants().ToArray();

            return(from node in ancestorsToChildren
                   where node.Method is not null
                   let allMakersNode = new MarkedNode(node, GetAllMarkers(node, markerInterface, context).Select(t => t.Item2))
                                       where allMakersNode.Definitions.Any() && IsIncludedByPointcut(allMakersNode, context) //&& !IsDeclaredByValue(node)
                                       let includedMarkersNode = new MarkedNode(node, allMakersNode.Definitions.Where(d => IsIncludedByNode(d, node, context)))
                                                                 where includedMarkersNode.Definitions.Any()
                                                                 select includedMarkersNode);
        }
        /// <summary>
        /// Creates the pointcut rules from an advice attribute.
        /// The custom attribute provided has to be either <see cref="ExcludePointcutAttribute"/> or <see cref="IncludePointcutAttribute"/>
        /// If not the return <see cref="PointcutSelector"/> are empty
        /// </summary>
        /// <param name="customAttribute">The custom attribute.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector CreatePointcutSelector(CustomAttribute customAttribute, WeavingContext context)
        {
            var rules = new PointcutSelector();

            rules.IncludeRules.AddRange(CreatePointcutSelectorRule(customAttribute, context.IncludePointcutAttributeType));
            rules.ExcludeRules.AddRange(CreatePointcutSelectorRule(customAttribute, context.ExcludePointcutAttributeType));
            return(rules);
        }
 /// <summary>
 /// Gets the rules at given <see cref="MarkedNode"/>.
 /// </summary>
 /// <param name="markedNode">The marked node.</param>
 /// <param name="context">The context.</param>
 /// <returns></returns>
 private IEnumerable <PointcutSelector> GetPointcutSelectors(MarkedNode markedNode, WeavingContext context)
 {
     return(markedNode.Definitions.Select(d => GetPointcutSelector(d.Type, context)));
 }
        /// <summary>
        /// Creates the pointcut rules from an advice attribute.
        /// The custom attribute provided has to be either <see cref="ExcludePointcutAttribute"/> or <see cref="IncludePointcutAttribute"/>
        /// If not the returned <see cref="PointcutSelector"/> is empty
        /// </summary>
        /// <param name="customAttribute">The custom attribute.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private PointcutSelector CreatePointcutSelector(CustomAttribute customAttribute, WeavingContext context)
        {
            var pointcutSelector = new PointcutSelector();

            if (context.IncludePointcutAttributeType != null)
            {
                pointcutSelector.IncludeRules.AddRange(CreatePointcutSelectorRule(customAttribute, context.IncludePointcutAttributeType));
            }
            if (context.ExcludePointcutAttributeType != null)
            {
                pointcutSelector.ExcludeRules.AddRange(CreatePointcutSelectorRule(customAttribute, context.ExcludePointcutAttributeType));
            }
            return(pointcutSelector);
        }
 /// <summary>
 /// Introduces the member.
 /// </summary>
 /// <param name="moduleDefinition">The module definition.</param>
 /// <param name="memberName">Name of the member.</param>
 /// <param name="memberType">Type of the member.</param>
 /// <param name="isStatic">if set to <c>true</c> [is static].</param>
 /// <param name="adviceType">The advice.</param>
 /// <param name="advisedType">The type definition.</param>
 /// <param name="markerAttribute">The marker attribute ctor.</param>
 /// <param name="introducedMemberName">Name of the introduced member.</param>
 /// <param name="isNotSerialized">if set to <c>true</c> [is not serialized].</param>
 /// <param name="context">The context.</param>
 private void IntroduceMember(ModuleDef moduleDefinition, string memberName, ITypeDefOrRef memberType, bool isStatic,
                              ITypeDefOrRef adviceType, TypeDef advisedType, ICustomAttributeType markerAttribute, string introducedMemberName, bool isNotSerialized, WeavingContext context)
 {
     if (IsIntroduction(memberType, out var introducedFieldType, out var isShared, context))
     {
         var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, introducedMemberName, memberName, isShared);
         lock (advisedType.Fields)
         {
             if (advisedType.Fields.All(f => f.Name != introducedFieldName))
             {
                 var fieldAttributes = (InjectAsPrivate ? FieldAttributes.Private : FieldAttributes.Public)
                                       | (isNotSerialized ? FieldAttributes.NotSerialized : 0);
                 if (isStatic)
                 {
                     fieldAttributes |= FieldAttributes.Static;
                 }
                 Logging.WriteDebug("Introduced field type '{0}'", introducedFieldType.FullName);
                 var introducedFieldTypeReference = TypeImporter.Import(moduleDefinition, introducedFieldType.ToTypeSig());
                 var introducedField = new FieldDefUser(introducedFieldName, new FieldSig(introducedFieldTypeReference), fieldAttributes);
                 introducedField.CustomAttributes.Add(new CustomAttribute(markerAttribute));
                 advisedType.Fields.Add(introducedField);
             }
         }
     }
 }
Beispiel #26
0
        private static IEnumerable <FieldDef> GetRemovableFields(IList <MarkedNode> nodes, WeavingContext context)
        {
            var type = nodes.First().Node.Method.DeclaringType;
            // get all types
            var allRemovableFields = GetRemovableFields(type.Methods, context);
            // then all referenced fields that will be dereferenced
            var toBeRemovedFields = GetRemovableFields(nodes.Select(n => n.Node.Method), context);
            // and remove only where count are equals
            var removableFields = from t in toBeRemovedFields
                                  where allRemovableFields.Contains(t)
                                  select t.Item1;

            return(removableFields);
        }
Beispiel #27
0
        /// <summary>
        /// Gets all attributes that implement the given advice interface
        /// </summary>
        /// <param name="reflectionNode">The reflection node.</param>
        /// <param name="markerInterface">The advice interface.</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private IEnumerable <Tuple <ReflectionNode, MarkerDefinition> > GetAllMarkers(ReflectionNode reflectionNode, ITypeDefOrRef markerInterface, WeavingContext context)
        {
            var markers = reflectionNode.GetAncestorsToDescendants()
                          .Select(n => new { Node = n, Attributes = n.CustomAttributes })
                          .SelectMany(n => n.Attributes.Select(a => new { Node = n.Node, Attribute = a })
                                      .Where(a => !a.Attribute.AttributeType.DefinitionAssembly.IsSystem())
                                      .Select(a => new { Node = a.Node, Type = ResolveTypeOrGenericDefinition(a.Attribute.AttributeType) })
                                      .Where(t => IsMarker(t.Type, markerInterface)))
                          .Select(t => Tuple.Create(t.Node, GetMarkerDefinition(t.Type, context)));

            return(markers);
        }
Beispiel #28
0
        /// <summary>
        /// Determines whether the specified <see cref="ReflectionNode"/> allows the given <see cref="MarkerDefinition"/>.
        /// </summary>
        /// <param name="markerDefinition">The marker definition.</param>
        /// <param name="node">The node.</param>
        /// <param name="context">The context.</param>
        /// <returns>
        ///   <c>true</c> if [is included by node] [the specified node]; otherwise, <c>false</c>.
        /// </returns>
        private bool IsIncludedByNode(MarkerDefinition markerDefinition, ReflectionNode node, WeavingContext context)
        {
            var adviceSelector = GetAdviceSelector(node, context);
            var isIncluded     = adviceSelector.Select(markerDefinition.Type);

            if (!isIncluded)
            {
                Logging.WriteDebug("Method '{0}' excluded advice '{1}'", node.Method.FullName, markerDefinition.Type.FullName);
            }
            return(isIncluded);
        }
Beispiel #29
0
        private static IEnumerable <Tuple <FieldDef, int> > GetRemovableFields(IEnumerable <MethodDef> methods, WeavingContext context)
        {
            var allFields   = methods.SelectMany(m => GetRemovableFields(m, context));
            var fieldsCount = allFields.GroupBy(f => f);

            return(fieldsCount.Select(f => Tuple.Create(f.Key, f.Count())));
        }
Beispiel #30
0
        /// <summary>
        /// Determines whether the advice member is introduction, based on its type.
        /// </summary>
        /// <param name="adviceMemberTypeReference">The type reference.</param>
        /// <param name="introducedFieldType">Type of the introduced field.</param>
        /// <param name="isShared">if set to <c>true</c> the introduced field is shared among advices of the same type.</param>
        /// <param name="context">The context.</param>
        /// <returns>
        ///   <c>true</c> if the specified advice member type reference is introduction; otherwise, <c>false</c>.
        /// </returns>
        private bool IsIntroduction(ITypeDefOrRef adviceMemberTypeReference, out ITypeDefOrRef introducedFieldType, out bool isShared, WeavingContext context)
        {
            introducedFieldType = null;
            isShared            = false;
            var genericAdviceMemberTypeReference = adviceMemberTypeReference.TryGetGenericInstSig();

            if (genericAdviceMemberTypeReference is null)
            {
                return(false);
            }

            var genericAdviceMemberTypeDefinition = TypeResolver.Resolve(genericAdviceMemberTypeReference.GenericType.TypeDefOrRef);

            if (genericAdviceMemberTypeDefinition is null) // in DEBUG or bogus cases, this may not be resolved. Whatever, this is not our field
            {
                return(false);
            }

            if (!genericAdviceMemberTypeDefinition.ImplementsType(context.IntroducedFieldType, TypeResolver))
            {
                return(false);
            }

            introducedFieldType = genericAdviceMemberTypeReference.GenericArguments[0].ToTypeDefOrRef();
            isShared            = genericAdviceMemberTypeDefinition.ImplementsType(context.SharedIntroducedFieldType, TypeResolver);
            return(true);
        }