コード例 #1
0
        /// <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;
            }
        }
コード例 #2
0
 public void RemovePath()
 {
     while (MarkedNode.Source != null)
     {
         MarkedNode.RemoveHighlight();
         MarkedNode = MarkedNode.Source as NavigableNode;
     }
     MarkedNode = null;
 }
コード例 #3
0
ファイル: AspectWeaver.cs プロジェクト: freeman6/MrAdvice
        /// <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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
ファイル: AspectWeaver.cs プロジェクト: freeman6/MrAdvice
        /// <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);
        }
コード例 #6
0
        /// <summary>
        /// Weaves the method.
        /// </summary>
        /// <param name="moduleDefinition">The module definition.</param>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="adviceInterface">The advice interface.</param>
        /// <param name="types">The types.</param>
        private void WeaveMethod(ModuleDefinition moduleDefinition, MarkedNode markedMethod, TypeDefinition adviceInterface, Types types)
        {
            var method = markedMethod.Node.Method;

            try
            {
                WeaveAdvices(markedMethod, types);
                WeaveIntroductions(method, adviceInterface, moduleDefinition, types);
            }
            catch (Exception e)
            {
                Logger.WriteError("Error while weaving method '{0}': {1}", method.FullName, e);
            }
        }
コード例 #7
0
        /// <summary>
        /// Weaves the method.
        /// </summary>
        /// <param name="moduleDefinition">The module definition.</param>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="context">The context.</param>
        private void WeaveMethod(ModuleDef moduleDefinition, MarkedNode markedMethod, WeavingContext context)
        {
            var method = markedMethod.Node.Method;

            try
            {
                WeaveAdvices(markedMethod, context);
                WeaveIntroductions(method, moduleDefinition, context);
            }
            catch (Exception e)
            {
                Logging.WriteError("Error while weaving method '{0}': {1}", method.FullName, e);
            }
        }
コード例 #8
0
ファイル: AspectWeaver.cs プロジェクト: freeman6/MrAdvice
        /// <summary>
        /// Indicates if the node belongs to a computer-generated type
        /// </summary>
        /// <param name="markedMethod">The marked method.</param>
        /// <returns>
        ///   <c>true</c> if [is from computer generated type] [the specified marked method]; otherwise, <c>false</c>.
        /// </returns>
        private bool IsFromComputerGeneratedType(MarkedNode markedMethod)
        {
            var parentType = markedMethod.Node.GetSelfAndAncestors().OfType <TypeReflectionNode>().FirstOrDefault();

            if (parentType is null)
            {
                return(false);
            }
            var isFromComputerGeneratedType = parentType.CustomAttributes.Any(c => c.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName);

            if (isFromComputerGeneratedType)
            {
                Logging.WriteDebug("Not weaving method '{0}' (from generated type)", markedMethod.Node.Method.FullName);
            }
            return(isFromComputerGeneratedType);
        }
コード例 #9
0
        /// <summary>
        /// Gets an app-path xPath string from a VarNode id.
        /// It includes all the elements from the root.
        /// The root may not be the application, but a dialog or view, etc..
        /// If there is a problem, null is returned.
        /// </summary>
        /// <param name="id">A VarNode name.</param>
        /// <returns>xPath to the model node.</returns>
        private string getAppPathFromId(string id)
        {
            if (!Utilities.isGoodStr(id))
            {
                return(null);
            }
            MarkedNode mn = m_varNodes.get(id);

            if (mn == null)
            {
                return(null);
            }
            XmlPath xp = new XmlPath(mn.node);

            return(xp.xPath());
        }
コード例 #10
0
ファイル: RangefinderMap.cs プロジェクト: cvance5/syphermia
 public void TargetNode(Node node)
 {
     if (node != MarkedNode)
     {
         if (MarkedNode != null)
         {
             MarkedNode.RemoveHighlight();
             MarkedNode = null;
         }
         if (Contains(node))
         {
             MarkedNode = node as TargetableNode;
             MarkedNode.Highlight();
         }
     }
 }
コード例 #11
0
ファイル: AspectWeaver.cs プロジェクト: freeman6/MrAdvice
 /// <summary>
 /// Determines whether the specified method is weavable.
 /// </summary>
 /// <param name="markedMethod">The marked method.</param>
 /// <returns></returns>
 private static bool IsWeavable(MarkedNode markedMethod)
 {
     return(markedMethod.Node.Method.HasBody || markedMethod.Node.Method.IsPinvokeImpl);
 }
コード例 #12
0
 /// <summary>
 /// Determines whether the specified method is weavable.
 /// </summary>
 /// <param name="markedMethod">The marked method.</param>
 /// <returns></returns>
 private static bool IsWeavable(MarkedNode markedMethod)
 {
     return(markedMethod.Node.Method.HasBody || markedMethod.Node.Method.HasPInvokeInfo);
 }
コード例 #13
0
 /// <summary>
 /// Determines the result of a Simian sensation.
 /// Problems with sensors are not generally logged
 /// since they are frequently called and most are not
 /// fatal.
 /// </summary>
 /// <param name="sensorRef">A sensor expression in a rule.</param>
 /// <returns>true if the sensor detected its target.</returns>
 public bool sensation(EmptyElement sensorRef)
 {
     if (sensorRef.getName().Equals("window"))
     {                                                // is the window showing?
         string     id    = sensorRef.getValue("id"); // a VarNode
         string     title = sensorRef.getValue("title");
         MarkedNode mn    = null;
         if (Utilities.isGoodStr(id) && Utilities.isGoodStr(title))
         {                  // fetch the title from the model node via id + title
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null)
             {
                 return(false);
             }
             if (mn.node != null)
             {
                 title = m_GuiModel.selectToString(mn.node, title, "title");
             }
             if (!Utilities.isGoodStr(title))
             {
                 return(false);
             }
         }
         else if (id == null && title == null)
         {                   // get the main window title from the model
             title = m_Config.getDataBase() + m_GuiModel.getTitle();
         }
         if (title == null)
         {
             return(false);                                // model lacks title
         }
         if (Utilities.isGoodStr(title))
         {
             IntPtr winHand = FindWindow(null, title);
             if ((int)winHand != 0)
             {
                 AccessibilityHelper ah = new AccessibilityHelper(winHand);
                 // look for a titlebar
                 GuiPath             gPath = new GuiPath("1:NAMELESS");
                 AccessibilityHelper tah   = ah.SearchPath(gPath, this);
                 if (tah == null || !tah.Value.Equals(title))
                 {
                     return(false);
                 }
                 m_ah = ah;
                 return(true);
             }
         }
     }
     if (sensorRef.getName().Equals("tested"))
     {
         string id      = sensorRef.getValue("id");            // which controls
         string control = sensorRef.getValue("control");       // which controls
         string count   = sensorRef.getValue("count");         // indicates how many
         if (control != null && count == null)
         {
             return(false);
         }
         if (control == null && count != null)
         {
             return(false);
         }
         if (control == null && count == null && id == null)
         {
             return(false);
         }
         if (id != null)
         {
             MarkedNode mn = m_varNodes.get(id);
             if (mn != null)
             {
                 if (mn.mark == null)
                 {
                     return(false);
                 }
                 return(mn.mark.Equals("tested"));
             }
         }
         // if id fails to return a marked node, try a control count
         if (control != null)
         {
             int n = 0; int k = 0;
             if (control.Equals("view"))
             {
                 if (m_views == null)
                 {
                     m_views = new MarkedList(m_GuiModel, "//*[@role='view']");
                 }
                 n = m_views.Count();
                 k = m_views.Count("tested");
             }
             if (count.Equals("all") && n == k)
             {
                 return(true);
             }
             if (count.Equals("not-all") && k < n)
             {
                 return(true);
             }
             return(false);
         }
         return(false);
     }
     if (sensorRef.getName().Equals("glimpse"))
     {
         string id       = sensorRef.getValue("id");           // a VarNode
         string appPath  = sensorRef.getValue("on");           // an appPath
         string guiPath  = sensorRef.getValue("at");           // a giuPath
         string property = sensorRef.getValue("prop");         // an ah property
         string expect   = sensorRef.getValue("expect");       // value expected
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode    context = null;
         MarkedNode mn      = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null)
             {
                 return(false);
             }
             if (mn.node != null)
             {
                 context = mn.node;
             }
         }
         return(glimpse(context, appPath, guiPath, property, expect));
     }
     return(false);
 }
コード例 #14
0
 /// <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)));
 }
コード例 #15
0
ファイル: Simian.cs プロジェクト: bbriggs/FieldWorks
 /// <summary>
 /// Determines the result of a Simian action.
 /// When actions can't be performed the problem is logged
 /// and false is returned.
 /// </summary>
 /// <param name="actionRef">An action in a rule.</param>
 /// <returns>true if the action was initiated successfully.</returns>
 public bool doAction(EmptyElement actionRef)
 {
     if (actionRef.getName().Equals("launch"))
     {   // launch the specified application
         bool usedModel = false;
         string path = actionRef.getValue("path");
         if (path == null)
         {
             path = m_Config.getExePath();
             usedModel = true;
         }
         string name = actionRef.getValue("name");
         if (name == null) name = m_Config.getExeName();
         string args = actionRef.getValue("args");
         if (args == null && usedModel) args = m_Config.getExeArgs();
         string work = actionRef.getValue("work");
         if (work == null && usedModel) work = m_Config.getWorkDir();
         return LaunchApp(path, name, args, work);
     }
     if (actionRef.getName().Equals("mark"))
     {   // mark the node as indicated
         string id = actionRef.getValue("id"); // a VarNode
         if (id == null) return false;
         string As = actionRef.getValue("as"); // How to mark the node
         // As == null is valid for removing the mark.
         return m_views.Mark(id, As);
     }
     if (actionRef.getName().Equals("free"))
     {   // free the VarNode named
         string id = actionRef.getValue("id"); // the VarNode to free
         if (id == null) return false;
         m_varNodes.add(id, null);
     }
     if (actionRef.getName().Equals("choose"))
     {   // choose the control via the method and name it via id
         string control = actionRef.getValue("control"); // Type of the control to choose
         string id = actionRef.getValue("id"); // a VarNode
         string exclude = actionRef.getValue("exclude"); // How to choose
         string method = actionRef.getValue("method"); // How to choose
         if (!Utilities.isGoodStr(control)) return false;
         if (!Utilities.isGoodStr(id)) return false;
         if (!Utilities.isGoodStr(method)) return false;
         MarkedNode mn = null;
         if (control.Equals("view")) mn = m_views.Choose(method, exclude);
         if (mn == null)
         {
             m_log.writeEltTime("fail");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("was", "not known");
             m_log.endElt();
             return false;
         }
         else
         {
             m_varNodes.add(id, mn);
             m_log.writeEltTime("selected");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("as", id);
             m_log.endElt();
         }
     }
     if (actionRef.getName().Equals("nav"))
     {   // find a model path to the referenced node
         string to = actionRef.getValue("to"); // a VarNode
         string via = actionRef.getValue("via"); // a VarNode name, not set yet
         if (!Utilities.isGoodStr(to)) return false;
         MarkedNode mn = m_varNodes.get(to);
         if (mn == null) return false;
         // What kind of node is this?
         string role = XmlFiler.getStringAttr((XmlElement)mn.node, "role", "*not Found*");
         if (role.Equals("*not Found*")) return false;
         MarkedNode viaN = null;
         if (role.Equals("view"))
         {  // get the menu node via mn and name it "via"
             string xPath = "menubar//" + mn.node.Name + "[@role='menu']";
             XmlPath mPath = m_GuiModel.selectToXmlPath(null, xPath);
             if (mPath == null) return false; // really bad!
             XmlNode menuNode = mPath.ModelNode;
             if (menuNode == null) return false; // really bad again!
             viaN = new MarkedNode(menuNode, null);
             m_varNodes.add(via, viaN);
         }
         if (viaN == null) return false; // nothing more to do at the moment
     }
     if (actionRef.getName().Equals("click"))
     {   // click the specified control
         string id = actionRef.getValue("id"); // a VarNode
         string appPath = actionRef.getValue("on"); // an appPath
         string guiPath = actionRef.getValue("at"); // a giuPath
         string side = actionRef.getValue("side"); // "left" or "right"
         bool leftSide = true;
         if (side != null && side.Equals("right")) leftSide = false;
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode context = null;
         MarkedNode mn = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null || mn.node == null) return false;
             context = mn.node;
         }
         return click(context, appPath, guiPath, leftSide);
     }
     if (actionRef.getName().Equals("close"))
     {   // close the specified application
         if (m_proc != null) closeWindow(m_proc);
     }
     return true;
 }
コード例 #16
0
        /// <summary>
        /// Weaves the specified method.
        /// </summary>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="context">The context.</param>
        private void WeaveAdvices(MarkedNode markedMethod, WeavingContext context)
        {
            var method = markedMethod.Node.Method;

            // sanity check
            var moduleDefinition = (ModuleDefMD)method.Module;

            if (method.ReturnType.SafeEquivalent(moduleDefinition.CorLibTypes.Void))
            {
                var customAttributes = method.CustomAttributes;
                if (customAttributes.Any(c => c.AttributeType.Name == "AsyncStateMachineAttribute"))
                {
                    Logging.WriteWarning("Advising async void method '{0}' could confuse async advices. Consider switching its return type to async Task.",
                                         method.FullName);
                }
            }

            if (method.IsAbstract)
            {
                method.Attributes = (method.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Virtual;
                Logging.WriteDebug("Weaving abstract method '{0}'", method.FullName);
                WritePointcutBody(method, null, false, context);
            }
            else if (markedMethod.AbstractTarget)
            {
                Logging.WriteDebug("Weaving and abstracting method '{0}'", method.FullName);
                WritePointcutBody(method, null, true, context);
            }
            else
            {
                Logging.WriteDebug("Weaving method '{0}'", method.FullName);

                var methodName = method.Name;

                // create inner method
                const MethodAttributes attributesToKeep = MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.PInvokeImpl |
                                                          MethodAttributes.UnmanagedExport | MethodAttributes.HasSecurity |
                                                          MethodAttributes.RequireSecObject;
                var innerMethodAttributes = method.Attributes & attributesToKeep |
                                            (InjectAsPrivate ? MethodAttributes.Private : MethodAttributes.Public);
                string innerMethodName;
                if (method.IsGetter)
                {
                    innerMethodName = GetPropertyInnerGetterName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsSetter)
                {
                    innerMethodName = GetPropertyInnerSetterName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsAddOn)
                {
                    innerMethodName = GetEventInnerAdderName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsRemoveOn)
                {
                    innerMethodName = GetEventInnerRemoverName(GetSpecialOwnerName(methodName));
                }
                else
                {
                    innerMethodName = GetInnerMethodName(methodName);
                }
                var innerMethod = new MethodDefUser(innerMethodName, method.MethodSig, innerMethodAttributes);
                new MethodParameters(method).SetParamDefs(innerMethod);
                innerMethod.GenericParameters.AddRange(method.GenericParameters.Select(p => p.Clone(innerMethod)));
                innerMethod.ImplAttributes      = method.ImplAttributes;
                innerMethod.SemanticsAttributes = method.SemanticsAttributes;
                if (method.IsPinvokeImpl)
                {
                    innerMethod.ImplMap  = method.ImplMap;
                    method.ImplMap       = null;
                    method.IsPreserveSig = false;
                    method.IsPinvokeImpl = false;
                }
                else
                {
                    innerMethod.Body = method.Body;
                    method.Body      = new CilBody();
                }

                AddGeneratedAttribute(innerMethod, context);

                lock (method.DeclaringType)
                    method.DeclaringType.Methods.Add(innerMethod);

                WritePointcutBody(method, innerMethod, false, context);
            }
        }
コード例 #17
0
        /// <summary>
        /// Weaves the specified method.
        /// </summary>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="types">The types.</param>
        private void WeaveAdvices(MarkedNode markedMethod, Types types)
        {
            var method = markedMethod.Node.Method;

            // sanity check
            var moduleDefinition = method.Module;

            if (method.ReturnType.SafeEquivalent(moduleDefinition.SafeImport(typeof(void))))
            {
                var customAttributes = method.CustomAttributes;
                if (customAttributes.Any(c => c.AttributeType.Name == "AsyncStateMachineAttribute"))
                {
                    Logger.WriteWarning("Advising async void method '{0}' could confuse async advices. Consider switching its return type to async Task.", method.FullName);
                }
            }

            if (method.IsAbstract)
            {
                method.Attributes = (method.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Virtual;
                Logger.WriteDebug("Weaving abstract method '{0}'", method.FullName);
                WritePointcutBody(method, null, false);
            }
            else if (markedMethod.AbstractTarget)
            {
                Logger.WriteDebug("Weaving and abstracting method '{0}'", method.FullName);
                WritePointcutBody(method, null, true);
            }
            else
            {
                Logger.WriteDebug("Weaving method '{0}'", method.FullName);

                var methodName = method.Name;

                // our special recipe, with weaving advices
                var weavingAdvicesMarkers = GetAllMarkers(markedMethod.Node, types.WeavingAdviceAttributeType, types).ToArray();
                if (weavingAdvicesMarkers.Any())
                {
                    var typeDefinition             = markedMethod.Node.Method.DeclaringType;
                    var initialType                = TypeLoader.GetType(typeDefinition);
                    var weaverMethodWeavingContext = new WeaverMethodWeavingContext(typeDefinition, initialType, methodName, types);
                    foreach (var weavingAdviceMarker in weavingAdvicesMarkers)
                    {
                        var weavingAdviceType   = TypeLoader.GetType(weavingAdviceMarker.Type);
                        var weavingAdvice       = (IWeavingAdvice)Activator.CreateInstance(weavingAdviceType);
                        var methodWeavingAdvice = weavingAdvice as IMethodWeavingAdvice;
                        if (methodWeavingAdvice != null && !method.IsGetter && !method.IsSetter)
                        {
                            methodWeavingAdvice.Advise(weaverMethodWeavingContext);
                        }
                    }
                    if (weaverMethodWeavingContext.TargetMethodName != methodName)
                    {
                        methodName = method.Name = weaverMethodWeavingContext.TargetMethodName;
                    }
                }

                // create inner method
                const MethodAttributes attributesToKeep = MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.PInvokeImpl |
                                                          MethodAttributes.UnmanagedExport | MethodAttributes.HasSecurity |
                                                          MethodAttributes.RequireSecObject;
                var innerMethodAttributes = method.Attributes & attributesToKeep |
                                            (InjectAsPrivate ? MethodAttributes.Private : MethodAttributes.Public);
                string innerMethodName;
                if (method.IsGetter)
                {
                    innerMethodName = GetPropertyInnerGetterName(GetPropertyName(methodName));
                }
                else if (method.IsSetter)
                {
                    innerMethodName = GetPropertyInnerSetterName(GetPropertyName(methodName));
                }
                else
                {
                    innerMethodName = GetInnerMethodName(methodName);
                }
                var innerMethod = new MethodDefinition(innerMethodName, innerMethodAttributes, method.ReturnType);
                innerMethod.GenericParameters.AddRange(method.GenericParameters.Select(p => p.Clone(innerMethod)));
                innerMethod.ImplAttributes      = method.ImplAttributes;
                innerMethod.SemanticsAttributes = method.SemanticsAttributes;
                innerMethod.Parameters.AddRange(method.Parameters);
                if (method.IsPInvokeImpl)
                {
                    innerMethod.PInvokeInfo = method.PInvokeInfo;
                    // must be removed before attributes are updated (otherwise Cecil gets angry)
                    method.PInvokeInfo   = null;
                    method.IsPreserveSig = false;
                    method.IsPInvokeImpl = false;
                }
                else
                {
                    innerMethod.Body.InitLocals = method.Body.InitLocals;
                    innerMethod.Body.Instructions.AddRange(method.Body.Instructions);
                    innerMethod.Body.Variables.AddRange(method.Body.Variables);
                    innerMethod.Body.ExceptionHandlers.AddRange(method.Body.ExceptionHandlers);
                }

                WritePointcutBody(method, innerMethod, false);
                lock (method.DeclaringType)
                    method.DeclaringType.Methods.Add(innerMethod);
            }
        }
コード例 #18
0
        /// <summary>
        /// Weaves the specified method.
        /// </summary>
        /// <param name="markedMethod">The marked method.</param>
        /// <param name="context">The context.</param>
        private void WeaveAdvices(MarkedNode markedMethod, WeavingContext context)
        {
            var method = markedMethod.Node.Method;

            // sanity check
            if (!method.HasReturnType)
            {
                var customAttributes = method.CustomAttributes;
                if (customAttributes.Any(c => c.AttributeType.Name == "AsyncStateMachineAttribute"))
                {
                    Logging.WriteWarning("Advising async void method '{0}' could confuse async advices. Consider switching its return type to async Task.", method.FullName);
                }
            }

            if (method.IsAbstract)
            {
                method.Attributes = (method.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Virtual;
                Logging.WriteDebug("Weaving abstract method '{0}'", method.FullName);
                WritePointcutBody(method, null, false, context);
            }
            else if (markedMethod.AbstractTarget)
            {
                Logging.WriteDebug("Weaving and abstracting method '{0}'", method.FullName);
                WritePointcutBody(method, null, true, context);
            }
            else
            {
                Logging.WriteDebug("Weaving method '{0}'", method.FullName);

                var methodName = method.Name;

                // create inner method
                const MethodAttributes attributesToKeep = MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.PInvokeImpl |
                                                          MethodAttributes.UnmanagedExport | MethodAttributes.HasSecurity |
                                                          MethodAttributes.RequireSecObject;
                var innerMethodAttributes = method.Attributes & attributesToKeep |
                                            (InjectAsPrivate ? MethodAttributes.Private : MethodAttributes.Public);
                string innerMethodName;
                if (method.IsGetter)
                {
                    innerMethodName = GetPropertyInnerGetterName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsSetter)
                {
                    innerMethodName = GetPropertyInnerSetterName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsAddOn)
                {
                    innerMethodName = GetEventInnerAdderName(GetSpecialOwnerName(methodName));
                }
                else if (method.IsRemoveOn)
                {
                    innerMethodName = GetEventInnerRemoverName(GetSpecialOwnerName(methodName));
                }
                else
                {
                    innerMethodName = GetInnerMethodName(methodName);
                }
                var innerMethod = new MethodDefUser(innerMethodName, method.MethodSig, innerMethodAttributes);
                new MethodParameters(method).SetParamDefs(innerMethod);
                innerMethod.GenericParameters.AddRange(method.GenericParameters.Select(p => p.Clone(innerMethod)));
                innerMethod.ImplAttributes      = method.ImplAttributes;
                innerMethod.SemanticsAttributes = method.SemanticsAttributes;
                if (method.IsPinvokeImpl)
                {
                    innerMethod.ImplMap  = method.ImplMap;
                    method.ImplMap       = null;
                    method.IsPreserveSig = false;
                    method.IsPinvokeImpl = false;
                }
                else
                {
                    innerMethod.Body = method.Body;
                    method.Body      = new CilBody();
                }

                AddGeneratedAttribute(innerMethod, context);

                lock (method.DeclaringType)
                    method.DeclaringType.Methods.Add(innerMethod);

                var stepInfos = innerMethod.CustomDebugInfos.OfType <PdbAsyncMethodCustomDebugInfo>().SelectMany(d => d.StepInfos).ToArray();
                for (var stepInfoIndex = 0; stepInfoIndex < stepInfos.Length; stepInfoIndex++)
                {
                    var stepInfo = stepInfos[stepInfoIndex];
                    Logging.WriteDebug("Found stepInfo for '{0}'", stepInfo.BreakpointMethod.ToString());
                    if (stepInfo.BreakpointMethod.SafeEquivalent(method))
                    {
                        Logging.WriteDebug("Replacing '{0}' with '{1}'", stepInfo.BreakpointMethod.ToString(), innerMethod.ToString());
                        stepInfo.BreakpointMethod = innerMethod;
                        stepInfos[stepInfoIndex]  = stepInfo;
                    }
                }

                WritePointcutBody(method, innerMethod, false, context);
            }
        }
コード例 #19
0
 /// <summary>
 /// Determines the result of a Simian action.
 /// When actions can't be performed the problem is logged
 /// and false is returned.
 /// </summary>
 /// <param name="actionRef">An action in a rule.</param>
 /// <returns>true if the action was initiated successfully.</returns>
 public bool doAction(EmptyElement actionRef)
 {
     if (actionRef.getName().Equals("launch"))
     {               // launch the specified application
         bool   usedModel = false;
         string path      = actionRef.getValue("path");
         if (path == null)
         {
             path      = m_Config.getExePath();
             usedModel = true;
         }
         string name = actionRef.getValue("name");
         if (name == null)
         {
             name = m_Config.getExeName();
         }
         string args = actionRef.getValue("args");
         if (args == null && usedModel)
         {
             args = m_Config.getExeArgs();
         }
         string work = actionRef.getValue("work");
         if (work == null && usedModel)
         {
             work = m_Config.getWorkDir();
         }
         return(LaunchApp(path, name, args, work));
     }
     if (actionRef.getName().Equals("mark"))
     {                                         // mark the node as indicated
         string id = actionRef.getValue("id"); // a VarNode
         if (id == null)
         {
             return(false);
         }
         string As = actionRef.getValue("as");                 // How to mark the node
         // As == null is valid for removing the mark.
         return(m_views.Mark(id, As));
     }
     if (actionRef.getName().Equals("free"))
     {                                         // free the VarNode named
         string id = actionRef.getValue("id"); // the VarNode to free
         if (id == null)
         {
             return(false);
         }
         m_varNodes.add(id, null);
     }
     if (actionRef.getName().Equals("choose"))
     {                                                   // choose the control via the method and name it via id
         string control = actionRef.getValue("control"); // Type of the control to choose
         string id      = actionRef.getValue("id");      // a VarNode
         string exclude = actionRef.getValue("exclude"); // How to choose
         string method  = actionRef.getValue("method");  // How to choose
         if (!Utilities.isGoodStr(control))
         {
             return(false);
         }
         if (!Utilities.isGoodStr(id))
         {
             return(false);
         }
         if (!Utilities.isGoodStr(method))
         {
             return(false);
         }
         MarkedNode mn = null;
         if (control.Equals("view"))
         {
             mn = m_views.Choose(method, exclude);
         }
         if (mn == null)
         {
             m_log.writeEltTime("fail");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("was", "not known");
             m_log.endElt();
             return(false);
         }
         else
         {
             m_varNodes.add(id, mn);
             m_log.writeEltTime("selected");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("as", id);
             m_log.endElt();
         }
     }
     if (actionRef.getName().Equals("nav"))
     {                                           // find a model path to the referenced node
         string to  = actionRef.getValue("to");  // a VarNode
         string via = actionRef.getValue("via"); // a VarNode name, not set yet
         if (!Utilities.isGoodStr(to))
         {
             return(false);
         }
         MarkedNode mn = m_varNodes.get(to);
         if (mn == null)
         {
             return(false);
         }
         // What kind of node is this?
         string role = XmlFiler.getStringAttr((XmlElement)mn.node, "role", "*not Found*");
         if (role.Equals("*not Found*"))
         {
             return(false);
         }
         MarkedNode viaN = null;
         if (role.Equals("view"))
         {                  // get the menu node via mn and name it "via"
             string  xPath = "menubar//" + mn.node.Name + "[@role='menu']";
             XmlPath mPath = m_GuiModel.selectToXmlPath(null, xPath);
             if (mPath == null)
             {
                 return(false);                                   // really bad!
             }
             XmlNode menuNode = mPath.ModelNode;
             if (menuNode == null)
             {
                 return(false);                                      // really bad again!
             }
             viaN = new MarkedNode(menuNode, null);
             m_varNodes.add(via, viaN);
         }
         if (viaN == null)
         {
             return(false);                              // nothing more to do at the moment
         }
     }
     if (actionRef.getName().Equals("click"))
     {                                                 // click the specified control
         string id       = actionRef.getValue("id");   // a VarNode
         string appPath  = actionRef.getValue("on");   // an appPath
         string guiPath  = actionRef.getValue("at");   // a giuPath
         string side     = actionRef.getValue("side"); // "left" or "right"
         bool   leftSide = true;
         if (side != null && side.Equals("right"))
         {
             leftSide = false;
         }
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode    context = null;
         MarkedNode mn      = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null || mn.node == null)
             {
                 return(false);
             }
             context = mn.node;
         }
         return(click(context, appPath, guiPath, leftSide));
     }
     if (actionRef.getName().Equals("close"))
     {               // close the specified application
         if (m_proc != null)
         {
             closeWindow(m_proc);
         }
     }
     return(true);
 }