/** * Remove an statement * * @param statement */ private void remove(CtStatement statement) { if (statement.getParent() instanceof CtBlock) { ((CtBlock) statement.getParent()).removeStatement(statement); } else { CtCodeSnippetStatementImpl comment = new CtCodeSnippetStatementImpl(); comment.setValue("/*REMOVED*/"); statement.replace(comment); } }
protected CtMethod apply(CtMethod method, List<Statement> statements, int index) { CtMethod cloned_method = AmplificationHelper.cloneMethodTest(method, "_cf", 1000); CtStatement stmt = getAssertStatement(cloned_method).get(index); statements .stream() .forEach( c -> { stmt.insertBefore((CtStatement) c.getCtCodeFragment()); c.getCtCodeFragment().setParent(stmt.getParent()); }); return cloned_method; }
protected List<CtLocalVariable> getLocalVarInScope(CtStatement stmt) { List<CtLocalVariable> vars = new ArrayList<>(); try { CtBlock parentBlock = stmt.getParent(CtBlock.class); if (parentBlock != null) { boolean beforeCurrentStmt = true; int i = 0; List<CtStatement> stmts = parentBlock.getStatements(); while (beforeCurrentStmt && i < stmts.size()) { CtStatement currentStatement = stmts.get(i); i++; beforeCurrentStmt = beforeCurrentStmt && currentStatement != stmt; if (currentStatement instanceof CtLocalVariable) { vars.add((CtLocalVariable) currentStatement); } } vars.addAll(getLocalVarInScope(parentBlock)); } } catch (Exception e) { throw new RuntimeException(e); } return vars; }
/** * Resolves all the variables used by the snippet. The ones which are initialized and the ones * which are not * * @return True if the context was extracted successfully */ private boolean resolveDataContext(CtStatement statement) { needsInitialization = false; // Check some preconditions needed for the processor to run: // All variable access made inside the statement List<CtVariableAccess> access = statement.getElements(new TypeFilter<>(CtVariableAccess.class)); if (statement.getElements(new TypeFilter<>(CtThisAccess.class)).size() > 0) { mustSerializeThiz = new Preconditions().checkTypeRef(statement.getParent(CtClass.class).getReference()); } initialized = new HashSet<>(); // Get all THIZ field access from all invocations used in the element HashSet<CtInvocation> visited = new HashSet<>(); Stack<CtInvocation> invStack = new Stack<>(); invStack.addAll(statement.getElements(new TypeFilter<>(CtInvocation.class))); while (!invStack.empty()) { CtInvocation inv = invStack.pop(); if (!visited.contains(inv)) { visited.add(inv); CtBlock b; try { b = inv.getExecutable().getDeclaration().getBody(); } catch (NullPointerException ex) { b = null; } if (visibility(inv) != PUBLIC && b != null) { for (CtFieldAccess ta : b.getElements(new TypeFilter<CtFieldAccess>(CtFieldAccess.class))) { if (ta.getTarget() instanceof CtThisAccess || ta.getTarget() == null) { access.add(ta); // initialized.add(ta); } } for (CtInvocation i : b.getElements(new TypeFilter<CtInvocation>(CtInvocation.class))) { if (!visited.contains(i)) invStack.push(i); } } } } access = cleanRepeatedAccesses(access); setAccesses(access); // Find initialized variables of allowed types ControlFlowBuilder v = new ControlFlowBuilder(); CtMethod m = statement.getParent(CtMethod.class); if (m == null) return false; m.accept(v); ControlFlowGraph g = v.getResult(); g.simplify(); try { InitializedVariables vars = new InitializedVariables(); vars.run(ControlFlowBuilder.firstNode(g, statement)); for (CtVariableAccess a : access) { // A variable must be initialized if is local and is not a serializable field // Also if is not a constant. Constant get declared in the body of the microbenchmark if (isInitialized(a, statement, vars) && !isAConstant(a)) initialized.add(a); } } catch (NotFoundException e) { return false; } catch (StackOverflowError e) { System.out.print(g.toGraphVisText()); throw e; } needsInitialization = initialized.size() > 0; if (access.size() <= 0) return true; int i = 0; int replaced = 0; do { if (i == 0) replaced = 0; CtVariableAccess a = access.get(i); if (canBeReplacedByTarget(a)) { CtVariableAccess targetOfA = null; CtTargetedExpression ta = (CtTargetedExpression) a; if (ta.getTarget() != null) { if (ta.getTarget() instanceof CtVariableAccess) { targetOfA = (CtVariableAccess) ta.getTarget(); } else if (ta.getTarget() instanceof CtThisAccess) { mustSerializeThiz = true; } } else { mustSerializeThiz = true; } if (targetOfA != null) { if (!access.contains(targetOfA)) access.add(targetOfA); if (initialized.contains(a) && !initialized.contains(targetOfA)) initialized.add(targetOfA); } access.remove(a); if (initialized.contains(a)) initialized.remove(a); replaced++; } else i++; if (i >= access.size()) i = 0; } while (replaced > 0 || i != 0); return true; }
@Override public void process(CtConditional ctConditional) { CtStatement parent = ctConditional.getParent(CtStatement.class); while (!(parent.getParent() instanceof CtStatementList)) { parent = parent.getParent(CtStatement.class); } CtExpression condition = ctConditional.getCondition(); CtIf anIf = getFactory().Core().createIf(); anIf.setPosition(ctConditional.getPosition()); if (parent instanceof CtReturn) { if (!((CtReturn) parent).getReturnedExpression().equals(ctConditional)) { return; } CtReturn returnThen = (CtReturn) parent.clone(); CtReturn returnElse = (CtReturn) parent.clone(); returnThen.setReturnedExpression(ctConditional.getThenExpression()); returnElse.setReturnedExpression(ctConditional.getElseExpression()); List<CtTypeReference> typeCasts = ctConditional.getTypeCasts(); for (int i = 0; i < typeCasts.size(); i++) { CtTypeReference ctTypeReference = typeCasts.get(i); returnThen.getReturnedExpression().addTypeCast(ctTypeReference.clone()); returnElse.getReturnedExpression().addTypeCast(ctTypeReference.clone()); } anIf.setElseStatement(getFactory().Code().createCtBlock(returnElse)); anIf.setThenStatement(getFactory().Code().createCtBlock(returnThen)); } else if (parent instanceof CtAssignment) { CtAssignment assignment = (CtAssignment) parent; CtExpression ctExpression = assignment.getAssignment(); if (!ctExpression.equals(ctConditional)) { if (ctExpression instanceof CtBinaryOperator) { CtBinaryOperator ctBinaryOperator = (CtBinaryOperator) ctExpression; createAssignment(ctConditional, anIf, assignment); CtBinaryOperator cloneThen = ctBinaryOperator.clone(); CtBinaryOperator cloneElse = ctBinaryOperator.clone(); if (ctBinaryOperator.getLeftHandOperand().equals(ctConditional)) { cloneThen.setLeftHandOperand(ctConditional.getThenExpression()); ctConditional.getThenExpression().setParent(cloneThen); cloneElse.setLeftHandOperand(ctConditional.getElseExpression()); } else if (ctBinaryOperator.getRightHandOperand().equals(ctConditional)) { cloneThen.setRightHandOperand(ctConditional.getThenExpression()); cloneElse.setRightHandOperand(ctConditional.getElseExpression()); } cloneThen.getLeftHandOperand().setParent(cloneThen); cloneElse.getLeftHandOperand().setParent(cloneElse); ((CtAssignment) ((CtBlock) anIf.getThenStatement()).getStatement(0)) .setAssignment(cloneThen); ((CtAssignment) ((CtBlock) anIf.getElseStatement()).getStatement(0)) .setAssignment(cloneElse); } else { return; } } else { createAssignment(ctConditional, anIf, assignment); } } else if (parent instanceof CtLocalVariable) { CtLocalVariable localVariable = (CtLocalVariable) parent; if (!localVariable.getDefaultExpression().equals(ctConditional)) { return; } CtLocalVariable clone = localVariable.clone(); clone.setDefaultExpression(null); localVariable.insertBefore(clone); CtAssignment variableAssignment = getFactory() .Code() .createVariableAssignment(localVariable.getReference(), false, ctConditional); variableAssignment.setType(localVariable.getType().clone()); variableAssignment.setPosition(ctConditional.getPosition()); createAssignment(ctConditional, anIf, variableAssignment); } else if (parent instanceof CtInvocation) { CtInvocation invocation = (CtInvocation) parent; CtInvocation cloneThen = invocation.clone(); CtInvocation cloneElse = invocation.clone(); List arguments = cloneThen.getArguments(); boolean found = false; for (int i = 0; i < arguments.size(); i++) { Object o = arguments.get(i); if (o.equals(ctConditional)) { ctConditional.getThenExpression().setParent(invocation); arguments.set(i, ctConditional.getThenExpression()); ctConditional.getElseExpression().setParent(invocation); cloneElse.getArguments().set(i, ctConditional.getElseExpression()); found = true; break; } } if (!found) { return; } cloneThen.setParent(anIf); cloneElse.setParent(anIf); anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse)); anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen)); } else if (parent instanceof CtConstructorCall) { CtConstructorCall invocation = (CtConstructorCall) parent; CtConstructorCall cloneThen = invocation.clone(); CtConstructorCall cloneElse = invocation.clone(); List arguments = cloneThen.getArguments(); boolean found = false; for (int i = 0; i < arguments.size(); i++) { Object o = arguments.get(i); if (o.equals(ctConditional)) { arguments.set(i, ctConditional.getThenExpression()); cloneElse.getArguments().set(i, ctConditional.getElseExpression()); found = true; break; } } if (!found) { return; } cloneThen.setParent(anIf); cloneElse.setParent(anIf); anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse)); anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen)); } else if (parent instanceof CtIf) { CtIf elem = (CtIf) parent; if (!elem.getCondition().equals(ctConditional)) { return; } CtIf cloneThen = elem.clone(); cloneThen.setParent(anIf); CtIf cloneElse = elem.clone(); cloneElse.setParent(anIf); cloneThen.setCondition(ctConditional.getThenExpression()); ctConditional.getThenExpression().setParent(cloneThen); cloneElse.setCondition(ctConditional.getElseExpression()); ctConditional.getElseExpression().setParent(cloneElse); anIf.setElseStatement(getFactory().Code().createCtBlock(cloneElse)); anIf.setThenStatement(getFactory().Code().createCtBlock(cloneThen)); } else if (parent instanceof CtThrow) { return; } else if (parent instanceof CtLoop) { return; } else if (parent instanceof CtUnaryOperator) { return; } else { System.err.println(parent); throw new RuntimeException("Other " + parent.getClass()); } /*if(ctConditional.getThenExpression().getTypeCasts() == null || ctConditional.getThenExpression().getTypeCasts().isEmpty()) { ((CtExpression)anIf.getThenStatement()).setTypeCasts(ctConditional.getTypeCasts()); } if(ctConditional.getElseExpression().getTypeCasts() == null || ctConditional.getElseExpression().getTypeCasts().isEmpty()) { ((CtExpression) anIf.getElseStatement()) .setTypeCasts(ctConditional.getTypeCasts()); }*/ anIf.setCondition(condition); condition.setParent(anIf); parent.replace(anIf); }