package ca.uwaterloo.ece.qhanam.jrsrepair.mutation; import ca.uwaterloo.ece.qhanam.jrsrepair.SourceStatement; import ca.uwaterloo.ece.qhanam.jrsrepair.DocumentASTRewrite; import java.util.HashMap; import org.eclipse.jdt.core.dom.rewrite.*; import org.eclipse.jdt.core.dom.*; import org.eclipse.text.edits.*; public class AdditionMutation extends Mutation { private Block addedBlock; // The block that has been added containing the faulty and seed statements. public AdditionMutation(HashMap<String, DocumentASTRewrite> sourceFileContents, SourceStatement faulty, SourceStatement seed){ super(sourceFileContents, faulty, seed); } /** * Adds the seed statement to the AST right before the * faulty statement. */ @Override public void concreteMutate() throws Exception { /* Create a new block to insert in place of the deleted statement. */ this.addedBlock = (Block) this.rewrite.getAST().createInstance(Block.class); /* Make a copy of the seed statement and base it in the faulty statement's AST. */ ASTNode seedCopy = ASTNode.copySubtree(this.rewrite.getAST(), seed.statement); ASTNode faultyCopy = ASTNode.copySubtree(this.rewrite.getAST(), faulty.statement); /* Insert the seed and faulty statements into the new Block. */ ListRewrite lrwt = this.rewrite.getListRewrite(this.addedBlock, Block.STATEMENTS_PROPERTY); lrwt.insertFirst(seedCopy, null); lrwt.insertLast(faultyCopy, null); /* Replace the faulty statement with the new Block. */ rewrite.replace(faulty.statement, this.addedBlock, null); /* Modify the source code file. */ this.docrwt.resetModifiedDocument(); // Start with the original document to avoid the AST-doesn't-match-doc error. TextEdit edits = rewrite.rewriteAST(this.docrwt.modifiedDocument, null); edits.apply(this.docrwt.modifiedDocument, TextEdit.NONE); } /** * Removes the statement added in mutate(). */ @Override public void concreteUndo() throws Exception{ /* Undo the edit to the AST. */ this.rewrite.replace(this.addedBlock, this.faulty.statement, null); /* We need to write the undo changes back to the source file because of recursion. */ this.docrwt.resetModifiedDocument(); // Start with the original document to avoid the AST-doesn't-match-doc error. TextEdit edits = rewrite.rewriteAST(this.docrwt.modifiedDocument, null); edits.apply(this.docrwt.modifiedDocument, TextEdit.NONE); } @Override public String toString(){ return "Addition " + super.toString(); } }