protected List<List<Statement>> buildContext( InputContext inputContext, List<Statement> stmts, int targetIndex) { VarCartesianProduct varCartesianProduct = new VarCartesianProduct(); Statement statement = stmts.get(targetIndex); for (CtVariableReference var : statement.getInputContext().getVar()) { varCartesianProduct.addReplaceVar(var, valueCreator.createNull(var.getType())); List<CtVariableReference> candidates = inputContext.allCandidate(var.getType(), true, false); if (!candidates.isEmpty()) { varCartesianProduct.addReplaceVar( var, candidates.get(AmplificationHelper.getRandom().nextInt(candidates.size()))); } Statement cfLocalVar = getLocalVar(var.getType(), inputContext); if (cfLocalVar != null) { varCartesianProduct.addReplaceVar(var, cfLocalVar); } CtLocalVariable localVariable = createLocalVarFromMethodLiterals(currentMethod, var.getType()); if (localVariable != null) { varCartesianProduct.addReplaceVar(var, localVariable); } CtLocalVariable randomVar = valueCreator.createRandomLocalVar(var.getType()); if (randomVar != null) { varCartesianProduct.addReplaceVar(var, randomVar); } } return varCartesianProduct.apply(stmts, targetIndex); }
/** * replace assertTrue * * @param ctInvocation * @return */ private CtStatement replaceAssertTrueFalse(boolean type, CtInvocation<?> ctInvocation) { List<?> arguments = ctInvocation.getArguments(); CtIf newIf = ctInvocation.getFactory().Core().createIf(); Object elem1 = arguments.get(0); if (arguments.size() > 1) { elem1 = arguments.get(1); } if (!type) { CtExpression<Boolean> condition = ctInvocation.getFactory().Code().createCodeSnippetExpression("!(" + elem1 + ")"); newIf.setCondition(condition); } else { newIf.setCondition((CtExpression<Boolean>) elem1); } // newIf.setThenStatement(getFactory().Code().createCodeSnippetStatement( // Debug.class.getCanonicalName() + ".printPC(\"Path Condition: \")")); /* * CtBlock<Object> thenStatement = ctInvocation.getFactory().Core() * .createBlock(); // thenStatement.addStatement((getFactory().Code(). * createCodeSnippetStatement("System.out.println(\"Then...\")"))); * thenStatement.addStatement((getFactory().Code() * .createCodeSnippetStatement("System.out.println(" + * Debug.class.getCanonicalName() + ".getSolvedPC())"))); * newIf.setThenStatement(thenStatement); */ newIf.setThenStatement(createThen(ctInvocation)); return newIf; }
protected List<CtStatement> getAssertStatement(CtMethod method) { List<CtStatement> statements = Query.getElements(method, new TypeFilter(CtStatement.class)); return statements .stream() .filter(stmt -> stmt.getParent() instanceof CtBlock) .filter(stmt -> AmplificationChecker.isAssert(stmt)) .collect(Collectors.toList()); }
protected List<InputContext> getInputContexts(CtMethod method) { List<InputContext> inputContexts = new ArrayList<>(); List<CtStatement> statements = getAssertStatement(method); for (CtStatement stmt : statements) { Set<CtVariableReference> varRefs = new HashSet<>(); for (CtLocalVariable var : getLocalVarInScope(stmt)) { varRefs.add(method.getFactory().Code().createLocalVariableReference(var)); } inputContexts.add(new InputContext(varRefs)); } return inputContexts; }
protected CtLocalVariable createLocalVarFromMethodLiterals( CtMethod method, CtTypeReference type) { List<CtLiteral> literals = getLiterals(method) .stream() .filter(lit -> lit.getType() != null) .filter(lit -> lit.getType().equals(type)) .collect(Collectors.toList()); if (literals.isEmpty()) { return null; } CtLiteral lit = literals.get(AmplificationHelper.getRandom().nextInt(literals.size())); return type.getFactory().Code().createLocalVariable(type, "vc_" + count++, lit); }
protected List<List<Statement>> buildStatements(InputContext inputContext) { return coverageBycodeFragments .keySet() .stream() .map( cf -> { List<Statement> list = new ArrayList<>(2); list.add(cf.clone()); return list; }) .flatMap( list -> { InputContext cloneInputContext = inputContext.clone(); return buildContext(cloneInputContext, list, list.size() - 1).stream(); }) .collect(Collectors.toList()); }
public void reset(Coverage coverage, CtType testClass) { AmplificationHelper.reset(); literalsByMethod = new HashMap<>(); Set<CtType> codeFragmentsProvide = AmplificationHelper.computeClassProvider(testClass); List<Statement> codeFragmentsByClass = codeFragmentsProvide .stream() .flatMap( cl -> { List<CtStatement> list = Query.getElements(cl, new TypeFilter(CtStatement.class)); return list.stream(); }) .filter( stmt -> { try { return stmt.getParent() != null; } catch (Exception e) { return false; } }) .filter(stmt -> stmt.getParent() instanceof CtBlock) .filter(stmt -> !stmt.toString().startsWith("super")) .filter(stmt -> !stmt.toString().startsWith("this(")) .map(stmt -> new Statement(stmt)) .collect(Collectors.toList()); if (findClassUnderTest(testClass) != null) { coverageBycodeFragments = buildCodeFragmentFor(findClassUnderTest(testClass), coverage); } else { coverageBycodeFragments = new HashMap<>(); } Set<Integer> ids = new HashSet<>(); localVars = codeFragmentsByClass .stream() .filter(cf -> isValidCodeFragment(cf)) .filter(cf -> ids.add(cf.id())) .collect(Collectors.toList()); }
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; }
/** * replace assertNotNull * * @param ctInvocation * @return */ private CtStatement replaceAssertNotNull(CtInvocation<?> ctInvocation) { List<?> arguments = ctInvocation.getArguments(); CtIf newIf = ctInvocation.getFactory().Core().createIf(); Object elem1 = arguments.get(0); CtExpression<Boolean> condition = ctInvocation.getFactory().Code().createCodeSnippetExpression("(" + elem1 + ") != null"); newIf.setCondition(condition); // newIf.setThenStatement(getFactory().Code().createCodeSnippetStatement( // Debug.class.getCanonicalName() + ".printPC(\"Path Condition: \")")); /* * CtBlock<Object> thenStatement = ctInvocation.getFactory().Core() * .createBlock(); thenStatement .addStatement((getFactory().Code() * .createCodeSnippetStatement("System.out.println(\"Then...\")"))); * thenStatement.addStatement((getFactory().Code() * .createCodeSnippetStatement("System.out.println(" + * Debug.class.getCanonicalName() + ".getSolvedPC())"))); * newIf.setThenStatement(thenStatement); */ newIf.setThenStatement(createThen(ctInvocation)); return newIf; }
protected Statement getLocalVar(CtTypeReference type, InputContext inputContext) { List<Statement> list = localVars .stream() .filter(var -> var.getCtCodeFragment() != null) .filter(var -> type.equals(((CtLocalVariable) var.getCtCodeFragment()).getType())) .filter( var -> inputContext.getVariableOrFieldNamed( ((CtLocalVariable) var.getCtCodeFragment()).getSimpleName()) == null) .collect(Collectors.toList()); if (list.isEmpty()) { return null; } else { boolean localVarFind; while (!list.isEmpty()) { Statement localVar = list.remove(AmplificationHelper.getRandom().nextInt(list.size())); localVarFind = true; for (CtVariableReference var : localVar.getInputContext().getVar()) { CtVariableReference<?> candidate = inputContext.candidate(var.getType(), true); if (candidate == null) { localVarFind = false; break; } } if (localVarFind) { Statement cloneLocalVar = localVar.clone(); for (CtVariableReference var : localVar.getInputContext().getVar()) { try { CtVariableReference variable = cloneLocalVar.getInputContext().getVariableOrFieldNamed(var.getSimpleName()); cloneLocalVar .getInputContext() .getVariableOrFieldNamed(var.getSimpleName()) .replace(variable); } catch (Exception e) { continue; } return cloneLocalVar; } } } return null; } }
@Override public List<CtMethod> apply(CtMethod method) { currentMethod = method; List<CtMethod> newMethods = new ArrayList<>(); if (!coverageBycodeFragments.isEmpty()) { List<InputContext> inputContexts = getInputContexts(method); if (!inputContexts.isEmpty()) { int index = inputContexts.size() - 1; List<List<Statement>> statements = buildStatements(inputContexts.get(index)); for (List<Statement> list : statements) { try { newMethods.add(apply(method, list, index)); } catch (Exception e) { throw new RuntimeException(e); } } } } return AmplificationHelper.updateAmpTestToParent(newMethods, 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; }