/// <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; } }
public void RemovePath() { while (MarkedNode.Source != null) { MarkedNode.RemoveHighlight(); MarkedNode = MarkedNode.Source as NavigableNode; } MarkedNode = null; }
/// <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> /// 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> /// 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> /// 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); } }
/// <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); } }
/// <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); }
/// <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()); }
public void TargetNode(Node node) { if (node != MarkedNode) { if (MarkedNode != null) { MarkedNode.RemoveHighlight(); MarkedNode = null; } if (Contains(node)) { MarkedNode = node as TargetableNode; MarkedNode.Highlight(); } } }
/// <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); }
/// <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); }
/// <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); }
/// <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> /// 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; }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); }