/// <summary> /// Analyzes children of nodes in a particular file /// </summary> /// <param name="fileAction">The object containing the actions to run on the file</param> /// <param name="children">List of child nodes to check</param> /// <param name="level">Recursion level to avoid stack overflows</param> private bool AnalyzeChildren(FileActions fileAction, UstList <UstNode> children, int level, string parentNamespace = "", string parentClass = "") { bool containsActions = false; if (children == null || level > Constants.MaxRecursionDepth) { return(false); } foreach (var child in children) { try { switch (child.NodeType) { case IdConstants.AnnotationIdName: { var annotation = (Annotation)child; var compareToken = new AttributeToken() { Key = annotation.Identifier, Namespace = annotation.Reference.Namespace, Type = annotation.SemanticClassType }; _rootNodes.Attributetokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } break; } case IdConstants.UsingDirectiveIdName: { var compareToken = new UsingDirectiveToken() { Key = child.Identifier }; _rootNodes.Usingdirectivetokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } break; } case IdConstants.NamespaceIdName: { var compareToken = new NamespaceToken() { Key = child.Identifier }; _rootNodes.NamespaceTokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, child.Identifier)) { containsActions = true; } break; } case IdConstants.ClassIdName: { var classType = (ClassDeclaration)child; var baseToken = new ClassDeclarationToken() { FullKey = classType.BaseType }; _rootNodes.Classdeclarationtokens.TryGetValue(baseToken, out var token); if (token != null) { //In case of class declarations, add actions on the class by name, instead of property AddNamedActions(fileAction, token, classType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } token = null; string name = string.Concat(classType.Reference != null ? string.Concat(classType.Reference.Namespace, ".") : string.Empty, classType.Identifier); var nameToken = new ClassDeclarationToken() { FullKey = name }; _rootNodes.Classdeclarationtokens.TryGetValue(nameToken, out token); if (token != null) { //In case of class declarations, add actions on the class by name, instead of property AddNamedActions(fileAction, token, classType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, classType.Identifier)) { containsActions = true; } break; } case IdConstants.InterfaceIdName: { var interfaceType = (InterfaceDeclaration)child; var baseToken = new InterfaceDeclarationToken() { FullKey = interfaceType.BaseType }; InterfaceDeclarationToken token = null; if (!string.IsNullOrEmpty(interfaceType.BaseType)) { _rootNodes.InterfaceDeclarationTokens.TryGetValue(baseToken, out token); } if (token != null) { //In case of interface declarations, add actions on the interface by name, instead of property AddNamedActions(fileAction, token, interfaceType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } token = null; string name = string.Concat(interfaceType.Reference != null ? string.Concat(interfaceType.Reference.Namespace, ".") : string.Empty, interfaceType.Identifier); var nameToken = new InterfaceDeclarationToken() { FullKey = name }; _rootNodes.InterfaceDeclarationTokens.TryGetValue(nameToken, out token); if (token != null) { //In case of interface declarations, add actions on the interface by name, instead of property AddNamedActions(fileAction, token, interfaceType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace)) { containsActions = true; } break; } case IdConstants.MethodIdName: { var compareToken = new MethodDeclarationToken() { FullKey = string.Concat(child.Identifier) }; _rootNodes.MethodDeclarationTokens.TryGetValue(compareToken, out var token); if (token != null) { AddNamedActions(fileAction, token, child.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.InvocationIdName: { string overrideKey = string.Empty; InvocationExpression invocationExpression = (InvocationExpression)child; ////If we don't have a semantic analysis, we dont want to replace invocation expressions, otherwise we'll be replacing expressions regardless of their class/namespace if (string.IsNullOrEmpty(invocationExpression.SemanticOriginalDefinition)) { break; } var compareToken = new InvocationExpressionToken() { Key = invocationExpression.SemanticOriginalDefinition, Namespace = invocationExpression.Reference.Namespace, Type = invocationExpression.SemanticClassType }; _rootNodes.Invocationexpressiontokens.TryGetValue(compareToken, out var token); //Attempt a wildcard search, if applicable. This is invocation expression specific because it has to look inside the invocation expressions only if (token == null) { var wildcardMatches = _rootNodes.Invocationexpressiontokens.Where(i => i.Key.Contains("*")); if (wildcardMatches.Any()) { token = wildcardMatches.FirstOrDefault(i => compareToken.Key.WildcardEquals(i.Key) && compareToken.Namespace == i.Namespace && compareToken.Type == i.Type); if (token != null) { //We set the key so that we don't do another wildcard search during replacement, we just use the name as it was declared in the code overrideKey = compareToken.Key; } } //If the semanticClassType is too specific to apply to all TData types if (token == null) { if (invocationExpression.SemanticClassType.Contains('<')) { string semanticClassType = invocationExpression.SemanticClassType.Substring(0, invocationExpression.SemanticClassType.IndexOf('<')); compareToken = new InvocationExpressionToken() { Key = invocationExpression.SemanticOriginalDefinition, Namespace = invocationExpression.Reference.Namespace, Type = semanticClassType }; _rootNodes.Invocationexpressiontokens.TryGetValue(compareToken, out token); } } } if (token != null) { AddActions(fileAction, token, child.TextSpan, overrideKey); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.ElementAccessIdName: { ElementAccess elementAccess = (ElementAccess)child; var compareToken = new ElementAccessToken() { Key = elementAccess.Expression, FullKey = GetFullKey(elementAccess.Reference?.Namespace, elementAccess.SemanticClassType, elementAccess.Expression), Type = elementAccess.SemanticClassType, Namespace = elementAccess.Reference?.Namespace }; _rootNodes.ElementAccesstokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.MemberAccessIdName: { MemberAccess memberAccess = (MemberAccess)child; var compareToken = new MemberAccessToken() { Key = memberAccess.Name, FullKey = GetFullKey(memberAccess.Reference?.Namespace, memberAccess.SemanticClassType, memberAccess.Name), Type = memberAccess.SemanticClassType, Namespace = memberAccess.Reference?.Namespace }; _rootNodes.MemberAccesstokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.DeclarationNodeIdName: { var declarationNode = (DeclarationNode)child; var compareToken = new IdentifierNameToken() { Key = string.Concat(declarationNode.Reference.Namespace, ".", declarationNode.Identifier), Namespace = declarationNode.Reference.Namespace }; _rootNodes.Identifiernametokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.ObjectCreationIdName: { var objectCreationNode = (ObjectCreationExpression)child; //Rules based on Object Creation Parent Hierarchy var compareToken = new ObjectCreationExpressionToken() { Key = objectCreationNode.Identifier, Namespace = objectCreationNode.Reference?.Namespace, Type = objectCreationNode.SemanticClassType }; _rootNodes.ObjectCreationExpressionTokens.TryGetValue(compareToken, out var token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } //Rules based on Object Creation location within code var compareTokenLocation = new ObjectCreationExpressionToken() { Key = objectCreationNode.Identifier, Namespace = parentNamespace, Type = parentClass }; _rootNodes.ObjectCreationExpressionTokens.TryGetValue(compareTokenLocation, out var tokenLocation); if (tokenLocation != null) { AddActions(fileAction, tokenLocation, child.TextSpan); containsActions = true; } token = null; if (!string.IsNullOrEmpty(objectCreationNode.SemanticOriginalDefinition)) { var nameToken = new ObjectCreationExpressionToken() { Key = objectCreationNode.SemanticOriginalDefinition, Namespace = objectCreationNode.SemanticNamespace, Type = objectCreationNode.SemanticClassType }; _rootNodes.ObjectCreationExpressionTokens.TryGetValue(nameToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } default: { if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } } } catch (Exception ex) { LogHelper.LogError(ex, "Error loading actions for item {0} of type {1}", child.Identifier, child.NodeType); } } return(containsActions); }
/// <summary> /// Processes each rule object by creating tokens and associated actions /// </summary> /// <param name="rootobject">An object containing tokens and actions to run on these tokens</param> private void ProcessObject(Rootobject rootobject) { var namespaces = rootobject.NameSpaces; foreach (var @namespace in namespaces) { if (@namespace.Actions != null && @namespace.Actions.Count > 0) { //Global Actions: if (@namespace.@namespace == Constants.Project && @namespace.Assembly == Constants.Project) { var projectToken = _rootNodes.ProjectTokens.FirstOrDefault(); ParseActions(projectToken, @namespace.Actions); } //Namespace specific actions: else { var usingToken = new UsingDirectiveToken() { Key = @namespace.@namespace }; var namespaceToken = new NamespaceToken() { Key = @namespace.@namespace }; if (!_rootNodes.Usingdirectivetokens.Contains(usingToken)) { _rootNodes.Usingdirectivetokens.Add(usingToken); } if (!_rootNodes.NamespaceTokens.Contains(namespaceToken)) { _rootNodes.NamespaceTokens.Add(namespaceToken); } ParseActions(usingToken, @namespace.Actions); ParseActions(namespaceToken, @namespace.Actions); } } foreach (var @class in @namespace.Classes) { if (@class.Actions != null && @class.Actions.Count > 0) { if (@class.KeyType == CTA.Rules.Config.Constants.BaseClass || @class.KeyType == CTA.Rules.Config.Constants.ClassName) { var token = new ClassDeclarationToken() { Key = @class.FullKey, FullKey = @class.FullKey, Namespace = @namespace.@namespace }; if (!_rootNodes.Classdeclarationtokens.Contains(token)) { _rootNodes.Classdeclarationtokens.Add(token); } ParseActions(token, @class.Actions); } else if (@class.KeyType == CTA.Rules.Config.Constants.Identifier) { var token = new IdentifierNameToken() { Key = @class.FullKey, FullKey = @class.FullKey, Namespace = @namespace.@namespace }; if (!_rootNodes.Identifiernametokens.Contains(token)) { _rootNodes.Identifiernametokens.Add(token); } ParseActions(token, @class.Actions); } } foreach (var attribute in @class.Attributes) { if (attribute.Actions != null && attribute.Actions.Count > 0) { var token = new AttributeToken() { Key = attribute.Key, Namespace = @namespace.@namespace, FullKey = attribute.FullKey, Type = @class.Key }; if (!_rootNodes.Attributetokens.Contains(token)) { _rootNodes.Attributetokens.Add(token); } ParseActions(token, attribute.Actions); } } foreach (var method in @class.Methods) { if (method.Actions != null && method.Actions.Count > 0) { var token = new InvocationExpressionToken() { Key = method.Key, Namespace = @namespace.@namespace, FullKey = method.FullKey, Type = @class.Key }; if (!_rootNodes.Invocationexpressiontokens.Contains(token)) { _rootNodes.Invocationexpressiontokens.Add(token); } ParseActions(token, method.Actions); } } foreach (var objectCreation in @class.ObjectCreations) { if (objectCreation.Actions != null && objectCreation.Actions.Count > 0) { var token = new ObjectCreationExpressionToken() { Key = objectCreation.Key, Namespace = @namespace.@namespace, FullKey = objectCreation.FullKey, Type = @class.Key }; if (!_rootNodes.ObjectCreationExpressionTokens.Contains(token)) { _rootNodes.ObjectCreationExpressionTokens.Add(token); } ParseActions(token, objectCreation.Actions); } } } foreach (var @interface in @namespace.Interfaces) { if (@interface.Actions != null && @interface.Actions.Count > 0) { if (@interface.KeyType == CTA.Rules.Config.Constants.BaseClass || @interface.KeyType == CTA.Rules.Config.Constants.InterfaceName) { var token = new InterfaceDeclarationToken() { Key = @interface.FullKey, FullKey = @interface.FullKey, Namespace = @namespace.@namespace }; if (!_rootNodes.InterfaceDeclarationTokens.Contains(token)) { _rootNodes.InterfaceDeclarationTokens.Add(token); } ParseActions(token, @interface.Actions); } else if (@interface.KeyType == CTA.Rules.Config.Constants.Identifier) { var token = new IdentifierNameToken() { Key = @interface.FullKey, FullKey = @interface.FullKey, Namespace = @namespace.@namespace }; if (!_rootNodes.Identifiernametokens.Contains(token)) { _rootNodes.Identifiernametokens.Add(token); } ParseActions(token, @interface.Actions); } } foreach (var attribute in @interface.Attributes) { if (attribute.Actions != null && attribute.Actions.Count > 0) { var token = new AttributeToken() { Key = attribute.Key, Namespace = @namespace.@namespace, FullKey = attribute.FullKey, Type = @interface.Key }; if (!_rootNodes.Attributetokens.Contains(token)) { _rootNodes.Attributetokens.Add(token); } ParseActions(token, attribute.Actions); } } foreach (var method in @interface.Methods) { if (method.Actions != null && method.Actions.Count > 0) { var token = new InvocationExpressionToken() { Key = method.Key, Namespace = @namespace.@namespace, FullKey = method.FullKey, Type = @interface.Key }; if (!_rootNodes.Invocationexpressiontokens.Contains(token)) { _rootNodes.Invocationexpressiontokens.Add(token); } ParseActions(token, method.Actions); } } } } }
/// <summary> /// Processes each rule object by creating tokens and associated actions /// </summary> /// <param name="rootobject">An object containing tokens and actions to run on these tokens</param> private void ProcessObject(NamespaceRecommendations namespaceRecommendations) { var namespaces = namespaceRecommendations.NameSpaces; foreach (var @namespace in namespaces) { foreach (var recommendation in @namespace.Recommendations) { RecommendedActions recommendedActions = recommendation.RecommendedActions .Where(ra => ra.Preferred == "Yes" && ra.TargetFrameworks.Any(t => t.Name.Equals(_targetFramework))).FirstOrDefault(); //There are recommendations, but none of them are preferred if (recommendedActions == null && recommendation.RecommendedActions.Count > 0) { LogHelper.LogError("No preferred recommendation set for recommendation {0} with target framework {1}", recommendation.Value, _targetFramework); continue; } else if (recommendedActions != null) { if (recommendedActions.Actions != null && recommendedActions.Actions.Count > 0) { var targetCPUs = new List <string> { "x86", "x64", "ARM64" }; try { targetCPUs = recommendedActions.TargetFrameworks.FirstOrDefault(t => t.Name == _targetFramework)?.TargetCPU; } catch { LogHelper.LogError("Error parsing CPUs for target framework"); } var recommendationType = Enum.Parse(typeof(ActionTypes), recommendation.Type); switch (recommendationType) { case ActionTypes.Namespace: { var usingToken = new UsingDirectiveToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs }; var namespaceToken = new NamespaceToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs }; if (!_rootNodes.Usingdirectivetokens.Contains(usingToken)) { _rootNodes.Usingdirectivetokens.Add(usingToken); } if (!_rootNodes.NamespaceTokens.Contains(namespaceToken)) { _rootNodes.NamespaceTokens.Add(namespaceToken); } ParseActions(usingToken, recommendedActions.Actions); ParseActions(namespaceToken, recommendedActions.Actions); break; } case ActionTypes.Class: { if (recommendation.KeyType == CTA.Rules.Config.Constants.BaseClass || recommendation.KeyType == CTA.Rules.Config.Constants.ClassName) { var token = new ClassDeclarationToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs, FullKey = recommendation.Value, Namespace = @namespace.Name }; if (!_rootNodes.Classdeclarationtokens.Contains(token)) { _rootNodes.Classdeclarationtokens.Add(token); } ParseActions(token, recommendedActions.Actions); } else if (recommendation.KeyType == CTA.Rules.Config.Constants.Identifier) { var token = new IdentifierNameToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs, FullKey = recommendation.Value, Namespace = @namespace.Name }; if (!_rootNodes.Identifiernametokens.Contains(token)) { _rootNodes.Identifiernametokens.Add(token); } ParseActions(token, recommendedActions.Actions); } break; } case ActionTypes.Interface: { if (recommendation.KeyType == CTA.Rules.Config.Constants.BaseClass || recommendation.KeyType == CTA.Rules.Config.Constants.ClassName) { var token = new InterfaceDeclarationToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs, FullKey = recommendation.Value, Namespace = @namespace.Name }; if (!_rootNodes.InterfaceDeclarationTokens.Contains(token)) { _rootNodes.InterfaceDeclarationTokens.Add(token); } ParseActions(token, recommendedActions.Actions); } else if (recommendation.KeyType == CTA.Rules.Config.Constants.Identifier) { var token = new IdentifierNameToken() { Key = recommendation.Value, Description = recommendedActions.Description, TargetCPU = targetCPUs, FullKey = recommendation.Value, Namespace = @namespace.Name }; if (!_rootNodes.Identifiernametokens.Contains(token)) { _rootNodes.Identifiernametokens.Add(token); } ParseActions(token, recommendedActions.Actions); } break; } case ActionTypes.Method: { var token = new InvocationExpressionToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.Invocationexpressiontokens.Contains(token)) { _rootNodes.Invocationexpressiontokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.Expression: { var token = new ExpressionToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.Expressiontokens.Contains(token)) { _rootNodes.Expressiontokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.Attribute: { var token = new AttributeToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.Attributetokens.Contains(token)) { _rootNodes.Attributetokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.ObjectCreation: { var token = new ObjectCreationExpressionToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.ObjectCreationExpressionTokens.Contains(token)) { _rootNodes.ObjectCreationExpressionTokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.MethodDeclaration: { var token = new MethodDeclarationToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.MethodDeclarationTokens.Contains(token)) { _rootNodes.MethodDeclarationTokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.ElementAccess: { var token = new ElementAccessToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.ElementAccesstokens.Contains(token)) { _rootNodes.ElementAccesstokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.MemberAccess: { var token = new MemberAccessToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value, Type = recommendation.ContainingType }; if (!_rootNodes.MemberAccesstokens.Contains(token)) { _rootNodes.MemberAccesstokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } case ActionTypes.Project: { var token = new ProjectToken() { Key = recommendation.Name, Description = recommendedActions.Description, TargetCPU = targetCPUs, Namespace = @namespace.Name, FullKey = recommendation.Value }; if (!_rootNodes.ProjectTokens.Contains(token)) { _rootNodes.ProjectTokens.Add(token); } ParseActions(token, recommendedActions.Actions); break; } default: break; } } } } } }
/// <summary> /// Analyzes children of nodes in a particular file /// </summary> /// <param name="fileAction">The object containing the actions to run on the file</param> /// <param name="children">List of child nodes to check</param> /// <param name="level">Recursion level to avoid stack overflows</param> private bool AnalyzeChildren(FileActions fileAction, UstList <UstNode> children, int level, string parentNamespace = "", string parentClass = "") { bool containsActions = false; if (children == null || level > Constants.MaxRecursionDepth) { return(false); } foreach (var child in children) { try { switch (child.NodeType) { case IdConstants.AnnotationIdName: { var annotation = (Annotation)child; var compareToken = new AttributeToken() { Key = annotation.Identifier, Namespace = annotation.Reference.Namespace, Type = annotation.SemanticClassType }; AttributeToken token = null; _rootNodes.Attributetokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } break; } case IdConstants.UsingDirectiveIdName: { var compareToken = new UsingDirectiveToken() { Key = child.Identifier }; UsingDirectiveToken token = null; _rootNodes.Usingdirectivetokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } break; } case IdConstants.NamespaceIdName: { var compareToken = new NamespaceToken() { Key = child.Identifier }; NamespaceToken token = null; _rootNodes.NamespaceTokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, child.Identifier)) { containsActions = true; } break; } case IdConstants.ClassIdName: { var classType = (ClassDeclaration)child; var baseToken = new ClassDeclarationToken() { FullKey = classType.BaseType }; ClassDeclarationToken token = null; _rootNodes.Classdeclarationtokens.TryGetValue(baseToken, out token); if (token != null) { //In case of class declarations, add actions on the class by name, instead of property AddNamedActions(fileAction, token, classType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } token = null; string name = string.Concat(classType.Reference != null ? string.Concat(classType.Reference.Namespace, ".") : string.Empty, classType.Identifier); var nameToken = new ClassDeclarationToken() { FullKey = name }; _rootNodes.Classdeclarationtokens.TryGetValue(nameToken, out token); if (token != null) { //In case of class declarations, add actions on the class by name, instead of property AddNamedActions(fileAction, token, classType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, classType.Identifier)) { containsActions = true; } break; } case IdConstants.InterfaceIdName: { var interfaceType = (InterfaceDeclaration)child; var baseToken = new InterfaceDeclarationToken() { FullKey = interfaceType.BaseType }; InterfaceDeclarationToken token = null; if (!string.IsNullOrEmpty(interfaceType.BaseType)) { _rootNodes.InterfaceDeclarationTokens.TryGetValue(baseToken, out token); } if (token != null) { //In case of interface declarations, add actions on the interface by name, instead of property AddNamedActions(fileAction, token, interfaceType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } token = null; string name = string.Concat(interfaceType.Reference != null ? string.Concat(interfaceType.Reference.Namespace, ".") : string.Empty, interfaceType.Identifier); var nameToken = new InterfaceDeclarationToken() { FullKey = name }; _rootNodes.InterfaceDeclarationTokens.TryGetValue(nameToken, out token); if (token != null) { //In case of interface declarations, add actions on the interface by name, instead of property AddNamedActions(fileAction, token, interfaceType.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace)) { containsActions = true; } break; } case IdConstants.MethodIdName: { var compareToken = new MethodDeclarationToken() { FullKey = string.Concat(child.Identifier) }; MethodDeclarationToken token = null; _rootNodes.MethodDeclarationTokens.TryGetValue(compareToken, out token); if (token != null) { AddNamedActions(fileAction, token, child.Identifier, child.TextSpan); AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.InvocationIdName: { InvocationExpression invocationExpression = (InvocationExpression)child; var compareToken = new InvocationExpressionToken() { Key = invocationExpression.MethodName, Namespace = invocationExpression.Reference.Namespace, Type = invocationExpression.SemanticClassType }; InvocationExpressionToken token = null; _rootNodes.Invocationexpressiontokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.DeclarationNodeIdName: { var declarationNode = (DeclarationNode)child; var compareToken = new IdentifierNameToken() { Key = string.Concat(declarationNode.Reference.Namespace, ".", declarationNode.Identifier), Namespace = declarationNode.Reference.Namespace }; IdentifierNameToken token = null; _rootNodes.Identifiernametokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } case IdConstants.ObjectCreationIdName: { var objectCreationNode = (ObjectCreationExpression)child; //Rules based on Object Creation Parent Hierarchy var compareToken = new ObjectCreationExpressionToken() { Key = objectCreationNode.Identifier, Namespace = objectCreationNode.Reference?.Namespace, Type = objectCreationNode.SemanticClassType }; ObjectCreationExpressionToken token = null; _rootNodes.ObjectCreationExpressionTokens.TryGetValue(compareToken, out token); if (token != null) { AddActions(fileAction, token, child.TextSpan); containsActions = true; } //Rules based on Object Creation location within code var compareTokenLocation = new ObjectCreationExpressionToken() { Key = objectCreationNode.Identifier, Namespace = parentNamespace, Type = parentClass }; ObjectCreationExpressionToken tokenLocation = null; _rootNodes.ObjectCreationExpressionTokens.TryGetValue(compareTokenLocation, out tokenLocation); if (tokenLocation != null) { AddActions(fileAction, tokenLocation, child.TextSpan); containsActions = true; } if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } default: { if (AnalyzeChildren(fileAction, child.Children, ++level, parentNamespace, parentClass)) { containsActions = true; } break; } } } catch (Exception ex) { LogHelper.LogError(ex, "Error loading actions for item {0} of type {1}", child.Identifier, child.NodeType); } } return(containsActions); }