Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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);
                        }
                    }
                }
            }
        }
Exemple #3
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }
Exemple #4
0
        /// <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);
        }