/** * Removes the current variable declaration from the AST and inserts it into the lowest possible * scope where the variable is first used. Returns the modification to the AST within a Change * object. */ private Change recordASTModifications() { AST ast = compilationUnit.getAST(); ASTRewrite rewriter = ASTRewrite.create(ast); // duplicate the original variable declaration in lower scope before getting rid of it VariableDeclarationStatement oldDeclaration = (VariableDeclarationStatement) variableVisitor.getDeclaration(); assert variableVisitor.getFirstAssignment() instanceof Assignment; Assignment variableAssignment = (Assignment) variableVisitor.getFirstAssignment(); ASTNode newScopeParent = variableAssignment.getParent().getParent(); String codeString = oldDeclaration.toString(); ASTNode newDeclaration = rewriter.createStringPlaceholder( codeString.substring(0, codeString.length() - 1), ASTNode.VARIABLE_DECLARATION_STATEMENT); ListRewrite listRewrite = rewriter.getListRewrite(newScopeParent, Block.STATEMENTS_PROPERTY); listRewrite.insertAt(newDeclaration, 0, null); // get rid of the higher scope declaration rewriter.remove(oldDeclaration, null); ICompilationUnit iCompUnit = method.getCompilationUnit(); final String description = "ReduceScopeOfVariable"; final String comment = "ReduceScopeOfVariable does blah..."; // record the change CompilationUnitChange change = new CompilationUnitChange("Reduce scope of variable", iCompUnit) { public ChangeDescriptor getDescriptor() { Map<Object, Object> arguments = new HashMap<Object, Object>(); arguments.put("method", method); arguments.put("var", varName); return new RefactoringChangeDescriptor( new ReduceScopeOfVariableDescriptor( method.getJavaProject().getElementName(), description, comment, arguments)); } }; try { change.setEdit(rewriter.rewriteAST()); } catch (Exception e) { } return change; }
private Example makeExample( MethodDeclaration node, Set<? extends Expression> envolvedInvocations, List<ApiMethod> envolvedApiMethods) { // Visitor responsável por realizar o slicing de programas SlicingStatementVisitor visitor = new SlicingStatementVisitor(node, new HashSet<ASTNode>(envolvedInvocations)); node.accept(visitor); Collection<Statement> relatedStatements = visitor.getSlicedStatements(); ASTNode newAST = ASTUtil.copyStatements(node.getBody(), relatedStatements, AST.newAST(AST.JLS3)); if (!relatedStatements.isEmpty()) { LOGGER.error("Some statements were not included!"); } if (newAST == null) { LOGGER.error("Slicing process failed for node "); // TODO Se AST retornada for nula é porque faltou incluir statement(s) return null; } else if (((Block) newAST).statements().isEmpty()) { LOGGER.error("Slicing process failed for node "); // TODO Se o Block retornado for vazio é porque faltou incluir statement(s) return null; } ASTUtil.removeEmptyBlocks((Block) newAST); // Adiciona declarações de variáveis que não foram encontradas no escopo do método // Para facilitar, tipos iguais são declarados no mesmo Statement Set<String> additionalDeclarationLines = new HashSet<String>(); Map<ITypeBinding, List<IVariableBinding>> typesMap = new HashMap<ITypeBinding, List<IVariableBinding>>(); for (IVariableBinding ivb : visitor.getUndiscoveredDeclarations()) { if (!typesMap.containsKey(ivb.getType())) { typesMap.put(ivb.getType(), new ArrayList<IVariableBinding>(2)); } typesMap.get(ivb.getType()).add(ivb); } for (ITypeBinding typeBinding : typesMap.keySet()) { List<IVariableBinding> variableBindings = typesMap.get(typeBinding); Stack<VariableDeclarationFragment> fragments = new Stack<VariableDeclarationFragment>(); for (IVariableBinding ivb : variableBindings) { VariableDeclarationFragment declarationFragment = newAST.getAST().newVariableDeclarationFragment(); declarationFragment.setName(newAST.getAST().newSimpleName(ivb.getName())); fragments.add(declarationFragment); } VariableDeclarationStatement statement = newAST.getAST().newVariableDeclarationStatement(fragments.pop()); while (!fragments.isEmpty()) { statement.fragments().add(fragments.pop()); } statement.setType(this.getType(typeBinding, newAST.getAST())); additionalDeclarationLines.add(statement.toString()); ((Block) newAST).statements().add(0, statement); } Example example = new Example(); example.setAttachment(this.attachmentMap.get(node.getRoot())); example.setApiMethods(new HashSet<ApiElement>(envolvedApiMethods)); example.setImports(visitor.getImports()); for (Expression seed : envolvedInvocations) { example.getSeeds().add(seed.toString()); } example.setSourceMethod(node.toString()); example.setAddedAt(new Date(System.currentTimeMillis())); try { IMethodBinding nodeBinding = node.resolveBinding(); if (!this.methodMap.containsKey(nodeBinding)) { ApiClass newApiClass = new ApiClass(nodeBinding.getDeclaringClass().getQualifiedName()); methodDeclarationHandler(node, newApiClass); } example.setSourceMethodCall(this.methodMap.get(nodeBinding).getFullName()); } catch (Exception e) { LOGGER.error(e); if (example.getSourceMethodCall() == null) { example.setSourceMethodCall("?"); } } String codeExample = newAST.toString(); for (String line : additionalDeclarationLines) { codeExample = codeExample.replace( line, line.replace("\n", "").concat(" ").concat("//initialized previously").concat("\n")); } // FIXME codeExample = codeExample.replaceAll("(\\{\n)(\\s+)(\\})", "$1 //do something \n$3"); try { example.setCodeExample(codeExample); example.setFormattedCodeExample(ASTUtil.codeFormatter(codeExample)); } catch (Exception e) { LOGGER.error(e); if (example.getFormattedCodeExample() == null) { example.setFormattedCodeExample(codeExample); } } // TODO Obter métricas do exemplo example .getMetrics() .put(ExampleMetric.LOC.name(), example.getFormattedCodeExample().split("\n").length - 1); example.getMetrics().put(ExampleMetric.ARGUMENTS.name(), visitor.getNumberOfArguments()); example .getMetrics() .put(ExampleMetric.DECISION_STATEMENTS.name(), visitor.getNumberOfDecisionStatements()); example.getMetrics().put(ExampleMetric.INVOCATIONS.name(), visitor.getNumberOfInvocations()); example .getMetrics() .put(ExampleMetric.NULL_ARGUMENTS.name(), visitor.getNumberOfNullArguments()); example .getMetrics() .put(ExampleMetric.PRIMITIVE_ARGUMENTS.name(), visitor.getNumberOfPrimitiveArguments()); example .getMetrics() .put(ExampleMetric.FIELD_ARGUMENTS.name(), visitor.getNumberOfFieldArguments()); example .getMetrics() .put( ExampleMetric.UNDISCOVERED_DECLARATIONS.name(), visitor.getNumberOfUndiscoveredDeclarations()); example .getMetrics() .put(ExampleMetric.UNHANDLED_EXCEPTIONS.name(), visitor.getNumberOfUnhandledExceptions()); return example; }