@Override protected String getCommonSuperClass(final String type1, final String type2) { final String key = type1 + "!_!" + type2; final String previous = this.cache.get(key); if (previous != null) { return previous; } final ClassReader info1 = typeInfo(type1); final ClassReader info2 = typeInfo(type2); final String result = getCommonSuperClass(type1, info1, type2, info2); this.cache.put(key, result); return result; }
private String getCommonSuperClass(final String type1, final ClassReader info1, final String type2, final ClassReader info2) { if (isInterface(info1)) { if (typeImplements(type2, info2, type1)) { return type1; } else { if (isInterface(info2)) { if (typeImplements(type1, info1, type2)) { return type2; } else { final StringBuilder b1 = typeAncestors(type1, info1); final StringBuilder b2 = typeAncestors(type2, info2); String result = "java/lang/Object"; int end1 = b1.length();
/** * Returns true if the given type implements the given interface. * * @param type * the internal name of a class or interface. * @param info * the ClassReader corresponding to 'type'. * @param itf * the internal name of a interface. * @return true if 'type' implements directly or indirectly 'itf' */ private boolean typeImplements(String type, ClassReader info, final String itf) { final String cleanItf = itf.replace(".", "/"); while (!"java/lang/Object".equals(type)) { final String[] itfs = info.getInterfaces(); for (final String itf2 : itfs) { if (itf2.equals(cleanItf)) { return true; } } for (final String itf2 : itfs) { if (typeImplements(itf2, typeInfo(itf2), cleanItf)) { return true; } } type = info.getSuperName(); info = typeInfo(type); } return false; }
private final String callTesteeWith(final Class<?> first, final Class<?> second) { return this.testee.getCommonSuperClass(ClassName.fromClass(first) .asInternalName(), ClassName.fromClass(second).asInternalName()); }
@Override public Mutant getMutation(final MutationIdentifier id) { final ClassContext context = new ClassContext(); context.setTargetMutation(Optional.ofNullable(id)); final Optional<byte[]> bytes = this.byteSource.getBytes(id.getClassName() .asJavaName()); final ClassReader reader = new ClassReader(bytes.get()); final ClassWriter w = new ComputeClassWriter(this.byteSource, this.computeCache, FrameOptions.pickFlags(bytes.get())); final MutatingClassVisitor mca = new MutatingClassVisitor(w, context, filterMethods(), FCollection.filter(this.mutators, isMutatorFor(id))); reader.accept(mca, ClassReader.EXPAND_FRAMES); final List<MutationDetails> details = context.getMutationDetails(context .getTargetMutation().get()); return new Mutant(details.get(0), w.toByteArray()); }
/** * Returns the internal names of the ancestor classes of the given type. * * @param type * the internal name of a class or interface. * @param info * the ClassReader corresponding to 'type'. * @return a StringBuilder containing the ancestor classes of 'type', * separated by ';'. The returned string has the following format: * ";type1;type2 ... ;typeN", where type1 is 'type', and typeN is a * direct subclass of Object. If 'type' is Object, the returned string * is empty. */ private StringBuilder typeAncestors(String type, ClassReader info) { final StringBuilder b = new StringBuilder(); while (!"java/lang/Object".equals(type)) { b.append(';').append(type); type = info.getSuperName(); info = typeInfo(type); } return b; }
/** * Returns true if the given type implements the given interface. * * @param type * the internal name of a class or interface. * @param info * the ClassReader corresponding to 'type'. * @param itf * the internal name of a interface. * @return true if 'type' implements directly or indirectly 'itf' */ private boolean typeImplements(String type, ClassReader info, final String itf) { final String cleanItf = itf.replace(".", "/"); while (!"java/lang/Object".equals(type)) { final String[] itfs = info.getInterfaces(); for (final String itf2 : itfs) { if (itf2.equals(cleanItf)) { return true; } } for (final String itf2 : itfs) { if (typeImplements(itf2, typeInfo(itf2), cleanItf)) { return true; } } type = info.getSuperName(); info = typeInfo(type); } return false; }
private byte[] transformBytes(final ClassLoader loader, final String className, final byte[] classfileBuffer) { final ClassReader reader = new ClassReader(classfileBuffer); final ClassWriter writer = new ComputeClassWriter( new ClassloaderByteArraySource(loader), this.computeCache, FrameOptions.pickFlags(classfileBuffer)); final int id = CodeCoverageStore.registerClass(className); reader.accept(new CoverageClassVisitor(id, writer), ClassReader.EXPAND_FRAMES); return writer.toByteArray(); }
/** * Returns the internal names of the ancestor classes of the given type. * * @param type * the internal name of a class or interface. * @param info * the ClassReader corresponding to 'type'. * @return a StringBuilder containing the ancestor classes of 'type', * separated by ';'. The returned string has the following format: * ";type1;type2 ... ;typeN", where type1 is 'type', and typeN is a * direct subclass of Object. If 'type' is Object, the returned string * is empty. */ private StringBuilder typeAncestors(String type, ClassReader info) { final StringBuilder b = new StringBuilder(); while (!"java/lang/Object".equals(type)) { b.append(';').append(type); type = info.getSuperName(); info = typeInfo(type); } return b; }
@Override protected String getCommonSuperClass(final String type1, final String type2) { final String key = type1 + "!_!" + type2; final String previous = this.cache.get(key); if (previous != null) { return previous; } final ClassReader info1 = typeInfo(type1); final ClassReader info2 = typeInfo(type2); final String result = getCommonSuperClass(type1, info1, type2, info2); this.cache.put(key, result); return result; }
private String getCommonSuperClass(final String type1, final ClassReader info1, final String type2, final ClassReader info2) { if (isInterface(info1)) { if (typeImplements(type2, info2, type1)) { return type1; } else { if (isInterface(info2)) { if (typeImplements(type1, info1, type2)) { return type2; } else { final StringBuilder b1 = typeAncestors(type1, info1); final StringBuilder b2 = typeAncestors(type2, info2); String result = "java/lang/Object"; int end1 = b1.length();
private static byte[] transformBytes(final ClassLoader loader, final String className, final byte[] classfileBuffer) { final ClassReader reader = new ClassReader(classfileBuffer); final ClassWriter writer = new ComputeClassWriter( new ClassloaderByteArraySource(loader), COMPUTE_CACHE, FrameOptions.pickFlags(classfileBuffer)); // The transformed classes will be given a different id than the one already loaded. // Not clear if this is desirable or not. At the point of writing this comment // pitest will merge coverage of all classes with the same fully qualified name. // If this changes this might become a bug, however it would also probably not be possible // to support powermock if this assumption changed, so this code would most likely be deleted. final int id = CodeCoverageStore.registerClass(className); reader.accept(new CoverageClassVisitor(id, writer), ClassReader.EXPAND_FRAMES); return writer.toByteArray(); }
@Override public Mutant getMutation(final MutationIdentifier id) { final ClassContext context = new ClassContext(); context.setTargetMutation(Optional.ofNullable(id)); final Optional<byte[]> bytes = this.byteSource.getBytes(id.getClassName() .asJavaName()); final ClassReader reader = new ClassReader(bytes.get()); final ClassWriter w = new ComputeClassWriter(this.byteSource, this.computeCache, FrameOptions.pickFlags(bytes.get())); final MutatingClassVisitor mca = new MutatingClassVisitor(w, context, filterMethods(), FCollection.filter(this.mutators, isMutatorFor(id))); reader.accept(mca, ClassReader.EXPAND_FRAMES); final List<MutationDetails> details = context.getMutationDetails(context .getTargetMutation().get()); return new Mutant(details.get(0), w.toByteArray()); }
private byte[] transformBytes(final ClassLoader loader, final String className, final byte[] classfileBuffer) { final ClassReader reader = new ClassReader(classfileBuffer); final ClassWriter writer = new ComputeClassWriter( new ClassloaderByteArraySource(loader), this.computeCache, FrameOptions.pickFlags(classfileBuffer)); final int id = CodeCoverageStore.registerClass(className); reader.accept(new CoverageClassVisitor(id, writer), ClassReader.EXPAND_FRAMES); return writer.toByteArray(); }
private static byte[] transformBytes(final ClassLoader loader, final String className, final byte[] classfileBuffer) { final ClassReader reader = new ClassReader(classfileBuffer); final ClassWriter writer = new ComputeClassWriter( new ClassloaderByteArraySource(loader), COMPUTE_CACHE, FrameOptions.pickFlags(classfileBuffer)); // The transformed classes will be given a different id than the one already loaded. // Not clear if this is desirable or not. At the point of writing this comment // pitest will merge coverage of all classes with the same fully qualified name. // If this changes this might become a bug, however it would also probably not be possible // to support powermock if this assumption changed, so this code would most likely be deleted. final int id = CodeCoverageStore.registerClass(className); reader.accept(new CoverageClassVisitor(id, writer), ClassReader.EXPAND_FRAMES); return writer.toByteArray(); }