/** * Copyright (C) 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mujava.op; import java.io.*; import openjava.mop.*; import openjava.ptree.*; /** * <p>Generate EMM (Java-specific modifier method change) mutants -- * change the modifier method name for other compatible modifier * method names. Note: <i>compatible</i> means that the signatures * are the same except the method name * </p> * <p><i>Example</i>: point.setX(2); is mutated to point.setY(2); * </p> * @author Yu-Seung Ma * @version 1.0 */ public class EMM extends mujava.op.util.Mutator { public EMM(FileEnvironment file_env, ClassDeclaration cdecl, CompilationUnit comp_unit) { super( file_env,comp_unit ); } public void visit( MethodCall p ) throws ParseTreeException { int i; MethodCall mutant= null; String method_name = p.getName(); if ((method_name.indexOf("set") == 0) && (p.getArguments().size() == 1)) { Environment env = getEnvironment(); Expression ref = p.getReferenceExpr(); // defined in same class OJClass bindedtype=null; if ( ref == null ) { bindedtype = env.lookupClass(env.currentClassName()); } else if (ref instanceof Variable) { bindedtype = env.lookupBind(ref.toString()); } if (bindedtype != null) { try { OJMethod[] m = bindedtype.getDeclaredMethods(); boolean[] find_flag = new boolean[m.length]; int method_index = -1; for ( i=0; i<m.length ; i++) { find_flag[i]=false; // find my method if ( m[i].getName().equals(method_name)) { method_index = i; break; } } if (method_index == -1) { m = bindedtype.getAllMethods(); find_flag = new boolean[m.length]; for ( i=0; i<m.length ; i++) { find_flag[i] = false; // find my method if ( m[i].getName().equals(method_name)) { method_index = i; break; } } } if (method_index == -1) return; int set_num = 0; for ( i=0; i<m.length; i++) { if ( (i != method_index) && (m[i].getName().indexOf("set") == 0) && sameReturnType(m[i], m[method_index]) && sameParameterType(m[i], m[method_index])) { find_flag[i] = true; set_num++; } } if (set_num > 0) { for (i=0; i<m.length; i++) { if (find_flag[i]) { mutant = (MethodCall)p.makeRecursiveCopy(); mutant.setName(m[i].getName()); outputToFile(p, mutant); } } return; } } catch (Exception e) { System.err.println(" [error] " + e); e.printStackTrace(); } } } Expression newp = this.evaluateDown( p ); if (newp != p) { p.replace( newp ); return; } p.childrenAccept( this ); newp = this.evaluateUp( p ); if (newp != p) p.replace( newp ); } /** * Output EMM mutants to files * @param original * @param mutant */ public void outputToFile (MethodCall original, MethodCall mutant) { if (comp_unit == null) return; String f_name; num++; f_name = getSourceName(this); String mutant_dir = getMuantID(); try { PrintWriter out = getPrintWriter(f_name); EMM_Writer writer = new EMM_Writer( mutant_dir, out ); writer.setMutant(original, mutant); comp_unit.accept( writer ); out.flush(); out.close(); } catch ( IOException e ) { System.err.println( "fails to create " + f_name ); } catch ( ParseTreeException e ) { System.err.println( "errors during printing " + f_name ); e.printStackTrace(); } } }