static ISet <SyntaxToken> validIdentifierNames(IdentifierNameSyntax identifierName, DataFlow dataFlow) { ISet <SyntaxToken> toReturn = new HashSet <SyntaxToken>(); ISet <SyntaxNode> defs = new HashSet <SyntaxNode>(); //Not totally satisfied with my method here. It feels jank, but due to the way I did the CFG and data flow, it is what works. if (dataFlow.containsReachingDef(identifierName)) { defs = dataFlow.GetReachingDefinitions(identifierName); } else if (dataFlow.containsReachingDef(identifierName.Parent)) { defs = dataFlow.GetReachingDefinitions(identifierName.Parent); } else if (dataFlow.containsReachingDef(identifierName.Parent.Parent)) { defs = dataFlow.GetReachingDefinitions(identifierName.Parent.Parent); } foreach (SyntaxNode def in defs) { String varName = DataFlow.getAssignmentOrLocalVarName(def); if (!varName.Equals(identifierName.Identifier.Text)) { toReturn.Add(SyntaxFactory.Identifier(varName)); } } return(toReturn); }
static ISet <SyntaxTree> traverseTreeForMutations(SyntaxNode node, SyntaxNode rootNode, DataFlow dataFlow) { ISet <SyntaxTree> mutationsForCurrentNode; MethodDeclarationSyntax methodDeclaration = node as MethodDeclarationSyntax; if (methodDeclaration != null) { ControlFlowGraph CFG = new ControlFlowGraph(methodDeclaration); dataFlow = new DataFlow(methodDeclaration, CFG); } mutationsForCurrentNode = getMutationsForNode(node, rootNode, dataFlow); foreach (SyntaxNode descendant in node.ChildNodes()) { mutationsForCurrentNode.UnionWith(traverseTreeForMutations(descendant, rootNode, dataFlow)); } return(mutationsForCurrentNode); }
static ISet <SyntaxTree> getMutationsForNode(SyntaxNode node, SyntaxNode rootNode, DataFlow optionalDataFlow = null) { ISet <SyntaxTree> toReturn = new HashSet <SyntaxTree>(); BinaryExpressionSyntax binaryExpression = node as BinaryExpressionSyntax; PostfixUnaryExpressionSyntax postfixUnaryExpression = node as PostfixUnaryExpressionSyntax; PrefixUnaryExpressionSyntax prefixUnaryExpression = node as PrefixUnaryExpressionSyntax; BlockSyntax block = node as BlockSyntax; StatementSyntax statement = node as StatementSyntax; IdentifierNameSyntax identifierName = node as IdentifierNameSyntax; if (binaryExpression != null) { ISet <SyntaxToken> validMutations = validBinaryOperatorMutations(binaryExpression); foreach (SyntaxToken mutatedToken in validMutations) { SyntaxNode newRoot = rootNode.ReplaceNode(node, binaryExpression.WithOperatorToken(mutatedToken).WithTrailingTrivia(syntaxTrivias)); toReturn.Add(newRoot.SyntaxTree); } } else if (postfixUnaryExpression != null) { ISet <SyntaxToken> validMutations = validUnaryOperatorMutations(postfixUnaryExpression); foreach (SyntaxToken mutatedToken in validMutations) { SyntaxNode newRoot = rootNode.ReplaceNode(node, postfixUnaryExpression.WithOperatorToken(mutatedToken).WithTrailingTrivia(syntaxTrivias)); toReturn.Add(newRoot.SyntaxTree); } } else if (prefixUnaryExpression != null) { ISet <SyntaxToken> validMutations = validUnaryOperatorMutations(prefixUnaryExpression); foreach (SyntaxToken mutatedToken in validMutations) { SyntaxNode newRoot = rootNode.ReplaceNode(node, prefixUnaryExpression.WithOperatorToken(mutatedToken).WithTrailingTrivia(syntaxTrivias)); toReturn.Add(newRoot.SyntaxTree); } } else if (statement != null && block == null) { //replace statements with semicolons toReturn.Add(rootNode.ReplaceNode(node, SyntaxFactory.EmptyStatement(SyntaxFactory.Token(SyntaxKind.SemicolonToken)).WithTrailingTrivia(syntaxTrivias)).SyntaxTree); } else if (identifierName != null && optionalDataFlow != null) { //Go through reaching definitions and replace with all other variables available ISet <SyntaxToken> validMutations = validIdentifierNames(identifierName, optionalDataFlow); foreach (SyntaxToken mutatedToken in validMutations) { SyntaxNode newRoot = rootNode.ReplaceNode(node, identifierName.WithIdentifier(mutatedToken).WithTrailingTrivia(syntaxTrivias)); toReturn.Add(newRoot.SyntaxTree); } } return(toReturn); }