Beispiel #1
0
        /// <summary>
        /// Tries to capture a potential field acccess in the given expression.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void TryCaptureFieldAccess(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!(expr is MemberAccessExpressionSyntax))
            {
                return;
            }

            var name = (expr as MemberAccessExpressionSyntax).Name;
            var identifier = context.GetFirstNonMachineIdentifier(expr, model);
            if (identifier == null || name == null)
            {
                return;
            }

            var type = model.GetTypeInfo(identifier).Type;
            if (context.IsTypeAllowedToBeSend(type) ||
                context.IsMachineType(type, model) ||
                name.Equals(identifier))
            {
                return;
            }

            var symbol = model.GetSymbolInfo(identifier).Symbol;
            var definition = SymbolFinder.FindSourceDefinitionAsync(symbol,
                context.Solution).Result;
            if (!(definition is IFieldSymbol))
            {
                return;
            }
            
            var fieldDecl = definition.DeclaringSyntaxReferences.First().GetSyntax().
                AncestorsAndSelf().OfType<FieldDeclarationSyntax>().First();
            if (dataFlowMap.DoesSymbolReset(symbol, cfgNode.Summary.Node.SyntaxNodes.First(),
                cfgNode.Summary.Node, syntaxNode, cfgNode, true))
            {
                return;
            }

            if (cfgNode.Summary.FieldAccessSet.ContainsKey(symbol as IFieldSymbol))
            {
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
            else
            {
                cfgNode.Summary.FieldAccessSet.Add(symbol as IFieldSymbol, new HashSet<SyntaxNode>());
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Tries to capture potential return symbols.
        /// </summary>
        /// <param name="returnSymbols">Set of return symbols</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        private static void TryCaptureReturnSymbols(HashSet<ISymbol> returnSymbols, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, SemanticModel model, DataFlowMap dataFlowMap)
        {
            Dictionary<ISymbol, HashSet<ISymbol>> map = null;
            if (returnSymbols == null ||
                !dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out map))
            {
                return;
            }

            Dictionary<ISymbol, int> indexMap = new Dictionary<ISymbol, int>();
            var parameterList = cfgNode.Summary.Method.ParameterList.Parameters;
            for (int idx = 0; idx < parameterList.Count; idx++)
            {
                var paramSymbol = model.GetDeclaredSymbol(parameterList[idx]);
                indexMap.Add(paramSymbol, idx);
            }

            foreach (var symbol in returnSymbols)
            {
                if (symbol.Kind == SymbolKind.Parameter)
                {
                    if (dataFlowMap.DoesSymbolReset(symbol, cfgNode.Summary.Node.SyntaxNodes.
                        First(), cfgNode.Summary.Node, syntaxNode, cfgNode, true))
                    {
                        continue;
                    }

                    cfgNode.Summary.ReturnSet.Item1.Add(indexMap[symbol]);
                }
                else if (symbol.Kind == SymbolKind.Field)
                {
                    cfgNode.Summary.ReturnSet.Item2.Add(symbol as IFieldSymbol);
                }
                else if (map.ContainsKey(symbol))
                {
                    foreach (var reference in map[symbol].Where(v => v.Kind == SymbolKind.Field))
                    {
                        cfgNode.Summary.ReturnSet.Item2.Add(reference as IFieldSymbol);
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Tries to capture a potential parameter acccess in the given expression.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void TryCaptureParameterAccess(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!(expr is MemberAccessExpressionSyntax))
            {
                return;
            }

            var name = (expr as MemberAccessExpressionSyntax).Name;
            var identifier = context.GetFirstNonMachineIdentifier(expr, model);
            if (identifier == null || name == null)
            {
                return;
            }

            var type = model.GetTypeInfo(identifier).Type;
            if (context.IsTypeAllowedToBeSend(type) ||
                context.IsMachineType(type, model) ||
                name.Equals(identifier))
            {
                return;
            }

            var symbol = model.GetSymbolInfo(identifier).Symbol;
            if (symbol == null)
            {
                return;
            }

            Dictionary<ISymbol, HashSet<ISymbol>> map = null;
            if (!dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out map))
            {
                return;
            }

            Dictionary<ISymbol, int> indexMap = new Dictionary<ISymbol, int>();
            var parameterList = cfgNode.Summary.Method.ParameterList.Parameters;
            for (int idx = 0; idx < parameterList.Count; idx++)
            {
                var paramSymbol = model.GetDeclaredSymbol(parameterList[idx]);
                indexMap.Add(paramSymbol, idx);
            }

            if (map.ContainsKey(symbol))
            {
                foreach (var reference in map[symbol])
                {
                    if (reference.Kind == SymbolKind.Parameter)
                    {
                        if (reference.Equals(symbol) && dataFlowMap.DoesSymbolReset(
                            reference, cfgNode.Summary.Node.SyntaxNodes.First(),
                            cfgNode.Summary.Node, syntaxNode, cfgNode, true))
                        {
                            continue;
                        }

                        int index = indexMap[reference];
                        if (cfgNode.Summary.AccessSet.ContainsKey(index))
                        {
                            cfgNode.Summary.AccessSet[index].Add(syntaxNode);
                        }
                        else
                        {
                            cfgNode.Summary.AccessSet.Add(index, new HashSet<SyntaxNode>());
                            cfgNode.Summary.AccessSet[index].Add(syntaxNode);
                        }
                    }
                }
            }
        }