/** * 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.*; import mujava.op.util.DeclAnalyzer; /** * <p>Generate OMD (Overloading method deletion) mutants -- * delete each overloaded method declaration, one at a time * </p> * @author Yu-Seung Ma * @version 1.0 */ public class OMD extends DeclAnalyzer { private final String[] primitives = { "char","short","int","long", "unsigned","unsigned long","float", "double","lond double"}; public void translateDefinition(CompilationUnit comp_unit) throws openjava.mop.MOPException { int i, j; OJMethod[] m = getDeclaredMethods(); boolean[] checked = new boolean[m.length]; int[] compatable_method = new int[m.length]; for (i=0; i<m.length; i++) { checked[i] = false; compatable_method[i] = -1; } // Check if overloading methods exist for (i=0; i< m.length; i++) { for (j=0; j<m.length; j++) { if (j != i) { if (omdPossible(m[i], m[j])) { checked[i] = true; compatable_method[i] = j; break; } } } } for (i=0; i<m.length; i++) { if (checked[i]) { try { MethodDeclaration original = m[i].getSourceCode(); outputToFile(comp_unit, original, m[compatable_method[i]]); // outputToFile(comp_unit,original,mutant_pars); } catch (CannotAlterException e) { System.err.println("[Error] " + e); e.printStackTrace(); } } } } private boolean omdPossible(OJMethod m1, OJMethod m2) { // step 1: it should be same name if ( !(m1.getName().equals(m2.getName())) ) return false; // step 2: it should have compatible index if ( m1.getParameterTypes().length == 0 ) return false; if ( m1.getParameterTypes().length != m2.getParameterTypes().length ) return false; int[] related_index = new int[m1.getParameterTypes().length]; related_index = getCompatibleParameterIndex(m1.getParameterTypes(),m2.getParameterTypes()); if (related_index != null) { return true; } return false; } private boolean same(OJClass[] s1, OJClass[] s2) { if (s1 == null && s2 == null) return true; else if (s1 == null || s2 == null) return false; if (s1.length != s2.length) return false; for (int i=0; i<s1.length; i++) { if ( !(s1[i].getName().equals(s2[i].getName())) ) return false; } return true; } private int getPrimitiveIndex(String s) { for (int i=0; i<primitives.length; i++) { if (s.equals(primitives[i])) return (i+1); } return 0; } private int relatedDifferentIndex(String small, String big) { int small_index = getPrimitiveIndex(small); int big_index = getPrimitiveIndex(big); if (small_index > 0) { if (big_index > 2) { // from int-> long -> ... ... if (big_index > small_index) return (big_index-small_index); } } else { try { String name = small; OJClass clazz; int temp = 0; while (true) { temp++; clazz = OJClass.forName(name).getSuperclass(); if ((clazz == null) || (clazz.getName().equals("java.lang.Object"))) return 0; name = clazz.getName(); if (name.equals("java.lang.Object")) return 0; if (big.equals(name)) return temp; } } catch (OJClassNotFoundException e) { return 0; //}catch(CannotAlterException cae){ // return false; } } return 0; } private int[] getCompatibleParameterIndex(OJClass[] smallP, OJClass[] bigP) { if ( smallP == null || bigP == null ) return null; if ( smallP.length != bigP.length ) return null; if ( same(smallP, bigP)) return null; int[] results = new int[smallP.length]; boolean diff = false; for (int i=0; i<smallP.length; i++) { results[i] = relatedDifferentIndex(smallP[i].getName(), bigP[i].getName()); if (results[i] != 0) diff = true; } if (!diff) return null; else return results; } /** * Output OMD mutants to files * @param comp_unit * @param original * @param mutant */ //public void outputToFile(CompilationUnit comp_unit,MethodDeclaration original,OJClass[] mutant_pars){ public void outputToFile(CompilationUnit comp_unit, MethodDeclaration original, OJMethod mutant) { if (comp_unit == null) return; String f_name; num++; f_name = getSourceName(this); String mutant_dir = getMuantID(); try { PrintWriter out = getPrintWriter(f_name); OMD_Writer writer = new OMD_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(); } } public OMD( openjava.mop.Environment oj_param0, openjava.mop.OJClass oj_param1, openjava.ptree.ClassDeclaration oj_param2 ) { super( oj_param0, oj_param1, oj_param2 ); } public OMD( java.lang.Class oj_param0, openjava.mop.MetaInfo oj_param1 ) { super( oj_param0, oj_param1 ); } }