code: /**
   * Copyright (C) . - All Rights Reserved.
   * Unauthorized copying of this file via any medium is
   * strictly prohibited Proprietary and Confidential.
   * Written by .
   */
  
  package pda.core.trace.inst.gen;
  
  import org.eclipse.jdt.core.dom.*;
  import pda.common.conf.Constant;
  import pda.common.utils.JavaFile;
  
  public class GenStatement {
  
  	private static AST ast = AST.newAST(Constant.AST_LEVEL);
  
  	/**
  	 * generate "System.out.println()" statement
  	 * 
  	 * @param expression
  	 * @return
  	 */
  	private static Statement genPrinter(Expression expression) {
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("System.out"));
  		methodInvocation.setName(ast.newSimpleName("println"));
  		methodInvocation.arguments().add(expression);
  		ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
  		return expressionStatement;
  	}
  
  	/**
  	 * generate write file statement "auxiliary.Dumper.write()"
  	 * 
  	 * @param expression
  	 * @return
  	 */
  	private static Statement genWriter(Expression expression) {
  		// auxiliary.Dumper.write(expression);
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		// change slowWriter to writer Jun@2018-1-13
  		// methodInvocation.setName(ast.newSimpleName("slowWrite"));
  		methodInvocation.setName(ast.newSimpleName("write"));
  		methodInvocation.arguments().add(expression);
  		ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
  		return expressionStatement;
  	}
  
  	/**
  	 * generate write file statement "auxiliary.Dumper.write(message)"
  	 * 
  	 * @param message
  	 * @return
  	 */
  	public static Statement genWriter(String message) {
  		StringLiteral literal = ast.newStringLiteral();
  		literal.setLiteralValue(message);
  		return genWriter(literal);
  	}
  
  	/**
  	 * generate printer {@code Statement} with the arguments as given
  	 * {@code locMessage} and {@code line}
  	 * 
  	 * @param locMessage
  	 * @param line
  	 * @return
  	 */
  	public static Statement genASTNode(String locMessage, int line) {
  		StringLiteral stringLiteral = ast.newStringLiteral();
  		stringLiteral.setLiteralValue(locMessage + "#" + line);
  		return genWriter(stringLiteral);
  	}
  
  	/**
  	 * generate predicate {@code IfStatement} and insert print line info
  	 * 
  	 * @param condition
  	 *                  : condition to be inserted
  	 * @param message
  	 *                  : location information
  	 * @param line
  	 *                  : line number
  	 * @return a if statement with a line number printer
  	 */
  	@Deprecated
  	public static IfStatement genPredicateStatement(String condition, String message, int line) {
  		IfStatement ifStatement = ast.newIfStatement();
  		Expression conditionExp = (Expression) JavaFile.genASTFromSource(condition, ASTParser.K_EXPRESSION);
  		ifStatement.setExpression((Expression) ASTNode.copySubtree(ast, conditionExp));
  		Statement statement = genASTNode(message, line);
  		Block thenBlock = ast.newBlock();
  		thenBlock.statements().add(statement);
  		ifStatement.setThenStatement(thenBlock);
  		return ifStatement;
  	}
  
  	public static Block genInstrumentStatementForTestWithReset(boolean succTest) {
  		Block block = ast.newBlock();
  
  		// auxiliary.Dumper.SUCC_TEST = succTest;
  		QualifiedName qName = ast.newQualifiedName(ast.newName("auxiliary.Dumper"), ast.newSimpleName("SUCC_TEST"));
  		Assignment assignment = ast.newAssignment();
  		assignment.setLeftHandSide(qName);
  		assignment.setRightHandSide(ast.newBooleanLiteral(succTest));
  		ExpressionStatement assignStatement = ast.newExpressionStatement(assignment);
  
  		// auxiliary.Dumper.reset();
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("reset"));
  		ExpressionStatement resetStatement = ast.newExpressionStatement(methodInvocation);
  
  		// {
  		// auxiliary.Dumper.SUCC_TEST = succTest;
  		// auxiliary.Dumper.reset();
  		// }
  		block.statements().add(assignStatement);
  		block.statements().add(resetStatement);
  
  		return block;
  	}
  
  	public static Block genInstrumentStatementForTestWithResetAndId(int method, boolean succTest) {
  		Block block = ast.newBlock();
  
  		// auxiliary.Dumper.SUCC_TEST = succTest;
  		QualifiedName qName = ast.newQualifiedName(ast.newName("auxiliary.Dumper"), ast.newSimpleName("SUCC_TEST"));
  		Assignment assignment = ast.newAssignment();
  		assignment.setLeftHandSide(qName);
  		assignment.setRightHandSide(ast.newBooleanLiteral(succTest));
  		ExpressionStatement assignStatement = ast.newExpressionStatement(assignment);
  
  		// auxiliary.Dumper.TEST_ID = method;
  		QualifiedName qName2 = ast.newQualifiedName(ast.newName("auxiliary.Dumper"), ast.newSimpleName("TEST_ID"));
  		Assignment assignment2 = ast.newAssignment();
  		assignment2.setLeftHandSide(qName2);
  		assignment2.setRightHandSide(ast.newNumberLiteral(String.valueOf(method)));
  
  		ExpressionStatement assignStatement2 = ast.newExpressionStatement(assignment2);
  
  		// auxiliary.Dumper.reset();
  		MethodInvocation methodInvocation2 = ast.newMethodInvocation();
  		methodInvocation2.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation2.setName(ast.newSimpleName("traceInit"));
  		ExpressionStatement resetStatement2 = ast.newExpressionStatement(methodInvocation2);
  
  		// auxiliary.Dumper.reset();
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("reset"));
  		ExpressionStatement resetStatement = ast.newExpressionStatement(methodInvocation);
  
  		// {
  		// auxiliary.Dumper.SUCC_TEST = succTest;
  		// auxiliary.Dumper.reset();
  		// }
  		block.statements().add(assignStatement);
  		block.statements().add(assignStatement2);
  		block.statements().add(resetStatement2);
  		block.statements().add(resetStatement);
  
  		return block;
  	}
  
  	public static Block genInstrumentStatementForTestWithResetTrueOrFalse(boolean succTest) {
  		Block block = genInstrumentStatementForTestWithReset(succTest);
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("resetTrueOrFalse"));
  		ExpressionStatement resetStatement = ast.newExpressionStatement(methodInvocation);
  		block.statements().add(resetStatement);
  		return block;
  	}
  
  	public static Block genInstrumentStatementForResultDump() {
  		Block block = ast.newBlock();
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("dump"));
  		ExpressionStatement dumpStatement = ast.newExpressionStatement(methodInvocation);
  		block.statements().add(dumpStatement);
  		return block;
  	}
  
  	public static Block genInstrumentStatementForResultDumpAndTrace() {
  		Block block = ast.newBlock();
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("dump"));
  		ExpressionStatement dumpStatement = ast.newExpressionStatement(methodInvocation);
  
  		MethodInvocation methodInvocation2 = ast.newMethodInvocation();
  		methodInvocation2.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation2.setName(ast.newSimpleName("dumpTrace"));
  		ExpressionStatement dumpStatement2 = ast.newExpressionStatement(methodInvocation2);
  
  		block.statements().add(dumpStatement);
  		block.statements().add(dumpStatement2);
  		return block;
  	}
  
  	public static Block genInstrumentStatementForResultDumpTrueOrFalse() {
  		Block block = ast.newBlock();
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("dumpTrueOrFalse"));
  		ExpressionStatement dumpStatement = ast.newExpressionStatement(methodInvocation);
  		block.statements().add(dumpStatement);
  		return block;
  	}
  
  	public static TryStatement newGenPredicateStatement(String condition, String message) {
  		Expression conditionExp = null;
  		// condition
  		try {
  			conditionExp = (Expression) JavaFile.genASTFromSource(condition, ASTParser.K_EXPRESSION);
  		} catch (Exception e) {
  			return null;
  		}
  
  		// if(condition)
  		IfStatement ifStatement = ast.newIfStatement();
  		ifStatement.setExpression((Expression) ASTNode.copySubtree(ast, conditionExp));
  
  		// auxiliary.Dumper.write(message);
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("write"));
  
  		StringLiteral stringLiteral = ast.newStringLiteral();
  		stringLiteral.setLiteralValue(message);
  		methodInvocation.arguments().add(stringLiteral);
  		ExpressionStatement invokeStatement = ast.newExpressionStatement(methodInvocation);
  
  		// if(condition){
  		// auxiliary.Dumper.write(message);
  		// }
  		Block thenBlock = ast.newBlock();
  		thenBlock.statements().add(invokeStatement);
  		ifStatement.setThenStatement(thenBlock);
  
  		// auxiliary.Dumper.observe(message);
  		MethodInvocation methodInvocation2 = ast.newMethodInvocation();
  		methodInvocation2.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation2.setName(ast.newSimpleName("observe"));
  
  		StringLiteral stringLiteral2 = ast.newStringLiteral();
  		stringLiteral2.setLiteralValue(message);
  		methodInvocation2.arguments().add(stringLiteral2);
  		ExpressionStatement invokeStatement2 = ast.newExpressionStatement(methodInvocation2);
  
  		// try{
  		// auxiliary.Dumper.observe(message);
  		// if(condition){
  		// auxiliary.Dumper.write(message);
  		// }
  		// }
  		Block tryBody = ast.newBlock();
  		tryBody.statements().add(invokeStatement2);
  		tryBody.statements().add(ifStatement);
  		TryStatement tryStatement = ast.newTryStatement();
  		tryStatement.setBody(tryBody);
  
  		// catch (Exception e){}
  		CatchClause catchClause = ast.newCatchClause();
  		SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
  		singleVariableDeclaration.setName(ast.newSimpleName("fakeException"));
  		singleVariableDeclaration.setType(ast.newSimpleType(ast.newSimpleName("Exception")));
  		catchClause.setException(singleVariableDeclaration);
  		catchClause.setBody(ast.newBlock());
  
  		// try{
  		// if(condition){
  		// auxiliary.Dumper.write(message);
  		// }
  		// }catch (Exception e){}
  		tryStatement.catchClauses().add(catchClause);
  
  		return tryStatement;
  	}
  
  	public static Block newGenPredicateStatementWithoutTry(String condition, String message) {
  		Expression conditionExp = null;
  		// condition
  		try {
  			conditionExp = (Expression) JavaFile.genASTFromSource(condition, ASTParser.K_EXPRESSION);
  		} catch (Exception e) {
  			return null;
  		}
  
  		// if(condition)
  		IfStatement ifStatement = ast.newIfStatement();
  		ifStatement.setExpression((Expression) ASTNode.copySubtree(ast, conditionExp));
  
  		// auxiliary.Dumper.write(message);
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("write"));
  
  		StringLiteral stringLiteral = ast.newStringLiteral();
  		stringLiteral.setLiteralValue(message);
  		methodInvocation.arguments().add(stringLiteral);
  		ExpressionStatement invokeStatement = ast.newExpressionStatement(methodInvocation);
  
  		// if(condition){
  		// auxiliary.Dumper.write(message);
  		// }
  		Block thenBlock = ast.newBlock();
  		thenBlock.statements().add(invokeStatement);
  		ifStatement.setThenStatement(thenBlock);
  
  		// auxiliary.Dumper.observe(message);
  		MethodInvocation methodInvocation2 = ast.newMethodInvocation();
  		methodInvocation2.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation2.setName(ast.newSimpleName("observe"));
  
  		StringLiteral stringLiteral2 = ast.newStringLiteral();
  		stringLiteral2.setLiteralValue(message);
  		methodInvocation2.arguments().add(stringLiteral2);
  		ExpressionStatement invokeStatement2 = ast.newExpressionStatement(methodInvocation2);
  
  		// try{
  		// auxiliary.Dumper.observe(message);
  		// if(condition){
  		// auxiliary.Dumper.write(message);
  		// }
  		// }
  		Block body = ast.newBlock();
  		body.statements().add(invokeStatement2);
  		body.statements().add(ifStatement);
  		return body;
  	}
  
  	public static TryStatement newGenPredicateStatementForEvaluationBias(String condition, String message) {
  		Expression conditionExp = null;
  		// condition
  		try {
  			conditionExp = (Expression) JavaFile.genASTFromSource(condition, ASTParser.K_EXPRESSION);
  		} catch (Exception e) {
  			return null;
  		}
  
  		// if(condition)
  		IfStatement ifStatement = ast.newIfStatement();
  		ifStatement.setExpression((Expression) ASTNode.copySubtree(ast, conditionExp));
  
  		// auxiliary.Dumper.writeTrue(message);
  		MethodInvocation methodInvocation = ast.newMethodInvocation();
  		methodInvocation.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation.setName(ast.newSimpleName("writeTrue"));
  
  		StringLiteral stringLiteral = ast.newStringLiteral();
  		stringLiteral.setLiteralValue(message);
  		methodInvocation.arguments().add(stringLiteral);
  		ExpressionStatement invokeStatement = ast.newExpressionStatement(methodInvocation);
  
  		// if(condition){
  		// auxiliary.Dumper.writeTrue(message);
  		// }
  		Block thenBlock = ast.newBlock();
  		thenBlock.statements().add(invokeStatement);
  		ifStatement.setThenStatement(thenBlock);
  
  		// auxiliary.Dumper.writeFalse(message);
  		MethodInvocation methodInvocation2 = ast.newMethodInvocation();
  		methodInvocation2.setExpression(ast.newName("auxiliary.Dumper"));
  		methodInvocation2.setName(ast.newSimpleName("writeFalse"));
  		StringLiteral stringLiteral2 = ast.newStringLiteral();
  		stringLiteral2.setLiteralValue(message);
  		methodInvocation2.arguments().add(stringLiteral2);
  		ExpressionStatement invokeStatement2 = ast.newExpressionStatement(methodInvocation2);
  
  		// if(condition){
  		// auxiliary.Dumper.writeTrue(message);
  		// } else {
  		// auxiliary.Dumper.writeFalse(message);
  		// }
  		Block elseBlock = ast.newBlock();
  		elseBlock.statements().add(invokeStatement2);
  		ifStatement.setElseStatement(elseBlock);
  
  		// try{
  		// if(condition){
  		// auxiliary.Dumper.writeTrue(message);
  		// } else {
  		// auxiliary.Dumper.writeFalse(message);
  		// }
  		// }
  		Block tryBody = ast.newBlock();
  		tryBody.statements().add(ifStatement);
  		TryStatement tryStatement = ast.newTryStatement();
  		tryStatement.setBody(tryBody);
  
  		// catch (Exception e){}
  		CatchClause catchClause = ast.newCatchClause();
  		SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
  		singleVariableDeclaration.setName(ast.newSimpleName("fakeException"));
  		singleVariableDeclaration.setType(ast.newSimpleType(ast.newSimpleName("Exception")));
  		catchClause.setException(singleVariableDeclaration);
  		catchClause.setBody(ast.newBlock());
  
  		// try{
  		// if(condition){
  		// auxiliary.Dumper.writeTrue(message);
  		// } else {
  		// auxiliary.Dumper.writeFalse(message);
  		// }
  		// }catch (Exception e){}
  		tryStatement.catchClauses().add(catchClause);
  
  		return tryStatement;
  	}
  }
  