/** * Create the content of the condition * * @param ctInvocation * @return */ private CtBlock<Object> createThen(CtInvocation<?> ctInvocation) { CtBlock<Object> thenStatement = ctInvocation.getFactory().Core().createBlock(); thenStatement.addStatement( (getFactory().Code().createCodeSnippetStatement("System.out.println(\"Else...\")"))); thenStatement.addStatement( (getFactory() .Code() .createCodeSnippetStatement( "System.out.println(" + Debug.class.getCanonicalName() + ".getSolvedPC())"))); CtAssert<Object> ctAssert = ctInvocation.getFactory().Core().createAssert(); CtCodeSnippetExpression<Boolean> assertExpression = getFactory().Core().createCodeSnippetExpression(); assertExpression.setValue("false"); ctAssert.setAssertExpression(assertExpression); ctAssert.setExpression( getFactory() .Code() .createCodeSnippetExpression( String.format("\"%s\"", ctInvocation.toString().replaceAll("\"", "'")))); thenStatement.addStatement(ctAssert); return thenStatement; }
private static <T> void processConstructor(CtConstructor<T> c, CtClass<T> toMerge) { CtStatement firstStmt = c.getBody().getStatements().get(0); if (firstStmt instanceof CtInvocation) { CtInvocation<?> superConstructorCall = (CtInvocation) firstStmt; if (!(superConstructorCall.getExecutable().getDeclaration() instanceof CtConstructor)) return; CtConstructor superConstructor = (CtConstructor) superConstructorCall.getExecutable().getDeclaration(); if (superConstructor.getDeclaringType() == toMerge) { CtBlock superConstructorBody = c.getFactory().Core().clone(superConstructor.getBody()); superConstructorBody.accept( new CtScanner() { @Override public <T> void visitCtParameterReference(CtParameterReference<T> ref) { int parameterOrder = superConstructor.getParameters().indexOf(ref.getDeclaration()); ref.setDeclaringExecutable(c.getReference()); CtExpression<?> arg = superConstructorCall.getArguments().get(parameterOrder); if (!(arg instanceof CtVariableAccess)) throw sgce("super() should be directly called in " + c); CtVariable param = ((CtVariableAccess) arg).getVariable().getDeclaration(); if (!(param instanceof CtParameter)) throw sgce("super() should be directly called in " + c); ref.setSimpleName(param.getSimpleName()); super.visitCtParameterReference(ref); } }); c.getBody().removeStatement(firstStmt); List<CtStatement> superConstructorBodyStatements = superConstructorBody.getStatements(); for (int i = superConstructorBodyStatements.size() - 1; i >= 0; i--) { c.getBody().insertBegin(superConstructorBodyStatements.get(i)); } } } }
private void createExecutionMethod(CtInvocation<?> ctInvocation) { CtClass<?> parent = ctInvocation.getParent(CtClass.class); if (!parent.isTopLevel()) { return; } if (parent.getModifiers().contains(ModifierKind.ABSTRACT)) { return; } CtTypeReference<String[]> typedReference = getFactory().Class().createReference(String[].class); if (parent.getMethod("runJPFTest", typedReference) != null) { return; } CtTypeReference<Object> returntypedReference = getFactory().Class().createReference("void"); Set<ModifierKind> modifiers = new LinkedHashSet<ModifierKind>(2); modifiers.add(ModifierKind.PUBLIC); modifiers.add(ModifierKind.STATIC); String invocation = parent.getQualifiedName() + "("; if (parent.getConstructor() == null) { // CtTypeReference<?> superClass = parent.getSuperclass(); if (parent.getConstructor(ctInvocation.getFactory().Class().STRING) != null) { invocation += "\"" + parent.getSimpleName() + "\""; } else { return; } } invocation += ")"; CtBlock<?> body = getFactory().Core().createBlock(); String bodyString = "for (String method : methods) {\n"; bodyString += "\t\tSystem.out.println(method);\n\t\t"; bodyString += parent.getQualifiedName() + " instance = new " + invocation + ";\n\t\t"; if (parent.getMethod("setUp") != null) { bodyString += "instance.setUp();"; } bodyString += parent.getQualifiedName() + ".class.getMethod(method, null).invoke(instance);\n\t\t"; bodyString += "}\n"; body.addStatement(getFactory().Code().createCodeSnippetStatement(bodyString)); HashSet<CtTypeReference<? extends Throwable>> exceptions = new HashSet<CtTypeReference<? extends Throwable>>(); exceptions.add(getFactory().Class().createReference(Exception.class)); CtMethod<?> method = getFactory() .Method() .create( parent, modifiers, returntypedReference, "runJPFTest", new ArrayList<CtParameter<?>>(), exceptions, body); getFactory().Method().createParameter(method, typedReference, "methods"); }
@Override public <R> void visitCtBlock(CtBlock<R> block) { int i = 0; while (i < block.getStatements().size()) { int size = block.getStatements().size(); CtStatement s = block.getStatement(i); s.accept(this); if (block.getStatements().size() >= size) i++; } }
/** * Replaces the element by an statement list containing all unary operators in the element * * @param element */ private void replaceByUnaryBlock(CtElement element) { CtBlock<CtUnaryOperator> opBlock = new CtBlockImpl<CtUnaryOperator>(); for (CtUnaryOperator s : element.getElements(new TypeFilter<CtUnaryOperator>(CtUnaryOperator.class))) if (s.getKind().compareTo(UnaryOperatorKind.PREINC) >= 0) { s.setParent(null); opBlock.addStatement(s); s.setParent(opBlock); } element.replace(opBlock); }
@Override public void process(CtClass<Bar> element) { // Creates new elements. final CtMethod prepareMojito = element.getMethodsByName("doSomething").get(0); prepareMojito.setSimpleName("prepareMojito"); prepareMojito.setType(getFactory().Type().VOID_PRIMITIVE); final CtBlock<Object> block = getFactory().Core().createBlock(); block.addStatement( getFactory().Code().createCodeSnippetStatement("System.out.println(\"Prepare mojito\")")); prepareMojito.setBody(block); final CtMethod makeMojito = prepareMojito.clone(); makeMojito.setSimpleName("makeMojito"); final CtBlock<Object> blockMake = getFactory().Core().createBlock(); blockMake.addStatement( getFactory().Code().createCodeSnippetStatement("System.out.println(\"Make mojito!\")")); makeMojito.setBody(blockMake); // Applies transformation. element.addMethod(makeMojito); elements.add(element); }
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; }
/** * Pretty print for the resulting degraded block * * @param clonedBody * @return */ public String prettyPrintBody(CtStatement clonedBody) { String result = ""; if (clonedBody instanceof CtBlock) { CtBlock block = (CtBlock) clonedBody; try { for (int i = 0; i < block.getStatements().size(); i++) { if (block.getStatement(i) instanceof CtBlock) result += prettyPrintBody(block.getStatement(i)); else if (block.getStatement(i) != null) result += block.getStatement(i).toString() + ";\n"; } } catch (NullPointerException ex) { log.error("Unable to print the degraded loop!"); } } else result = clonedBody.toString(); return result; }
/** * 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 <B extends R, T extends CtExecutable<R>> T setBody(CtBlock<B> body) { body.setParent(this); this.body = body; return (T) this; }