protected override ICodeIssueComputer CheckCondition(IDocument before, IDocument after, IManualExtractMethodRefactoring input) { // Calculate the outflow data IEnumerable<ISymbol> flowOuts; if (input.ExtractedStatements != null) flowOuts = GetFlowOutData(input.ExtractedStatements, before); else flowOuts = GetFlowOutData(input.ExtractedExpression, before); // Get the returning data of the return statements. var delaration = input.ExtractedMethodDeclaration; var methodAnalyzer = AnalyzerFactory.GetMethodDeclarationAnalyzer(); methodAnalyzer.SetMethodDeclaration(delaration); // Get the returning data in the return statements of the extracted method, also log them. var returningData = GetMethodReturningData(methodAnalyzer, after); // Missing symbols that are in the flow out before but not in the returning data. // Remove this symbol. var missing = ConditionCheckersUtils.RemoveThisSymbol( ConditionCheckersUtils.GetSymbolListExceptByName(flowOuts, returningData)); if (missing.Any()) { return new ReturnTypeCheckingResult(input.ExtractedMethodDeclaration, ConditionCheckersUtils.GetTypeNameTuples(missing)); } return new NullCodeIssueComputer(); }
protected override IConditionCheckingResult CheckCondition( IManualExtractMethodRefactoring refactoring) { var before = refactoring.BeforeDocument; // Calculate the outflow data var flowOuts = refactoring.ExtractedStatements != null ? GetFlowOutData(refactoring. ExtractedStatements, before) : GetFlowOutData(refactoring.ExtractedExpression, before); // Missing symbols that are in the flow out before but not in the returning data. // Remove this symbol. var missing = ConditionCheckersUtils.RemoveThisSymbol(flowOuts).ToList(); // Remove the returned symbol from the method declaration. missing = missing.Where(s => !GetReturnedIdentifiers(refactoring.ExtractedMethodDeclaration). Contains(s.Name)).ToList(); if (missing.Any()) { return new ReturnTypeCheckingResult(refactoring.ExtractedMethodDeclaration, refactoring.ExtractMethodInvocation, ConditionCheckersUtils.GetTypeNameTuples(missing) ,refactoring.MetaData); } return new SingleDocumentCorrectRefactoringResult(refactoring, RefactoringConditionType); }
protected override ICodeIssueComputer CheckCondition(IDocument before, IDocument after, IManualExtractMethodRefactoring input) { var invocation = (InvocationExpressionSyntax) input.ExtractMethodInvocation; // Calculate the needed typeNameTuples, depending on what to extract. IEnumerable<ISymbol> needed; if (input.ExtractedStatements != null) needed = ConditionCheckersUtils.GetFlowInData(input.ExtractedStatements, before); else needed = ConditionCheckersUtils.GetFlowInData(input.ExtractedExpression, before); // Logging the needed typeNameTuples. logger.Info("Needed typeNameTuples: " + StringUtil.ConcatenateAll(",", needed.Select(s => s.Name))); // Calculate the used symbols in the method declaration. var expressionDataFlowAnalyzer = AnalyzerFactory.GetExpressionDataFlowAnalyzer(); expressionDataFlowAnalyzer.SetDocument(after); expressionDataFlowAnalyzer.SetExpression(invocation); var used = expressionDataFlowAnalyzer.GetFlowInData(); // Logging the used typeNameTuples. logger.Info("Used typeNameTuples: " + StringUtil.ConcatenateAll(",", used.Select(s => s.Name))); // Calculate the missing symbols and the extra symbols, also, trivial to show 'this' so remove. var missing = ConditionCheckersUtils.RemoveThisSymbol( ConditionCheckersUtils.GetSymbolListExceptByName(needed, used)); // if missing is not empty, then some typeNameTuples are needed. if (missing.Any()) { logger.Info("Missing Parameters Issue Found."); return new ParameterCheckingCodeIssueComputer(input.ExtractedMethodDeclaration, ConditionCheckersUtils.GetTypeNameTuples(missing)); } else { // Otherwise, return no problem. return new NullCodeIssueComputer(); } }
protected override IConditionCheckingResult CheckCondition( IManualExtractMethodRefactoring refactoring) { var before = refactoring.BeforeDocument; // Calculate the needed typeNameTuples, depending on what to extract. IEnumerable<ISymbol> needed; if (refactoring.ExtractedStatements != null) needed = ConditionCheckersUtils.GetUsedButNotDeclaredData(refactoring.ExtractedStatements, before); else needed = ConditionCheckersUtils.GetFlowInData(refactoring.ExtractedExpression, before); // Logging the needed typeNameTuples. logger.Info("Needed typeNameTuples: " + StringUtil.ConcatenateAll(",", needed.Select(s => s.Name))); // Calculate the missing symbols and the extra symbols, also, trivial to show 'this' so // remove. needed = ConditionCheckersUtils.RemoveThisSymbol(needed); // Among the missing parameters, some of them are already by a parameter of the newly // extracted method. var parameterNames = GetParameterNames(refactoring.ExtractedMethodDeclaration); var missing = needed.Where(s => !parameterNames.Contains(s.Name)); // if missing is not empty, then some typeNameTuples are needed. if (missing.Any()) { logger.Info("Missing Parameters Issue Found."); return new ParameterCheckingCodeIssueComputer(refactoring.ExtractedMethodDeclaration, ConditionCheckersUtils.GetTypeNameTuples(missing), refactoring.MetaData); } // Otherwise, return no problem. return new SingleDocumentCorrectRefactoringResult(refactoring, this.RefactoringConditionType); }
protected abstract ICodeIssueComputer CheckCondition(IDocument before, IDocument after, IManualExtractMethodRefactoring input);
public bool CanGetRefactoring() { var commonStatements = new List<SyntaxNode>(); var commonExpressions = new List<SyntaxNode>(); // Get the block of the original method before extracting anything. var parentBlockBefore = ASTUtil.GetBlockOfMethod(parentMethodDeclarationBefore); // Get the block of the extracted method declaration. var extractedMethodBlock = ASTUtil.GetBlockOfMethod(extractedMethodDeclaration); // For each decendent node in the block of original method. foreach (var node in parentBlockBefore.DescendantNodes()) { // Care about statements. if (node is StatementSyntax) { // For each statement in the body of the extracted method foreach (var statement in extractedMethodBlock.DescendantNodes().Where(n => n is StatementSyntax)) { // If we some how think they are same, memorized that. if (AreNodesEqual(statement, node)) { commonStatements.Add(node); } } } // Care about expressions. if (node is ExpressionSyntax) { // For each expression in the block of the extracted method. foreach (var expression in extractedMethodBlock.DescendantNodes().Where(n => n is ExpressionSyntax)) { // If we somehow think they are same, memorize that. if (AreNodesEqual(expression, node)) { commonExpressions.Add(node); } } } } var analyzer = AnalyzerFactory.GetSyntaxNodesAnalyzer(); // First-class customer: has statements in common. if (commonStatements.Any()) { analyzer.SetSyntaxNodes(commonStatements); // Get the longest group of statements that are neighbors. var extractedStatements = analyzer.GetLongestNeighborredNodesGroup(); refactoring = ManualRefactoringFactory.CreateManualExtractMethodRefactoring (extractedMethodDeclaration, invocation, extractedStatements); return true; } // Second class customer: has expressions in common. if (commonExpressions.Any()) { analyzer.SetSyntaxNodes(commonExpressions); // Get the longest node among all the expressions; It is not possible to extract // several expressions at the same time. var extractedExpression = analyzer.GetLongestNode(); refactoring = ManualRefactoringFactory.CreateManualExtractMethodRefactoring (extractedMethodDeclaration, invocation, extractedExpression); return true; } return false; }
protected abstract IConditionCheckingResult CheckCondition( IManualExtractMethodRefactoring refactoring);