Skip to content

Commit eb539ae

Browse files
authored
Merge pull request #1433 from hcoles/feature/expand_method_tree_interface
expand MethodTree api
2 parents 22fc0ad + c7bea43 commit eb539ae

File tree

3 files changed

+208
-127
lines changed

3 files changed

+208
-127
lines changed

pitest-entry/src/main/java/org/pitest/bytecode/analysis/MethodTree.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public boolean isPrivate() {
7070
return (this.rawNode.access & Opcodes.ACC_PRIVATE) != 0;
7171
}
7272

73+
public boolean isAbstract() {
74+
return (this.rawNode.access & Opcodes.ACC_ABSTRACT) != 0;
75+
}
76+
77+
7378
public boolean returns(ClassName clazz) {
7479
return this.rawNode.desc.endsWith("L" + clazz.asInternalName() + ";");
7580
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.pitest.bytecode.analysis;
2+
3+
import org.junit.Test;
4+
import org.pitest.classpath.ClassloaderByteArraySource;
5+
6+
import static org.assertj.core.api.Assertions.assertThat;
7+
8+
public class MethodTreeTest {
9+
10+
ClassloaderByteArraySource bytes = ClassloaderByteArraySource.fromContext();
11+
12+
@Test
13+
public void recognisesAbstractMethods() {
14+
var clazz = loadClass(Bar.class.getName());
15+
var isAbstract = findMethod(clazz, "foo");
16+
var isConcrete = findMethod(clazz, "bar");
17+
18+
assertThat(isAbstract.isAbstract()).isTrue();
19+
assertThat(isConcrete.isAbstract()).isFalse();
20+
}
21+
22+
@Test
23+
public void recognisesAbstractMethodsInterfaces() {
24+
var clazz = loadClass(Foo.class.getName());
25+
var method = findMethod(clazz, "foo");
26+
27+
assertThat(method.isAbstract()).isTrue();
28+
}
29+
30+
@Test
31+
public void recognisesPrivateMethods() {
32+
var clazz = loadClass(Bar.class.getName());
33+
var isPrivate = findMethod(clazz, "cantSeeMe");
34+
var notPrivate = findMethod(clazz, "foo");
35+
36+
assertThat(isPrivate.isPrivate()).isTrue();
37+
assertThat(notPrivate.isPrivate()).isFalse();
38+
}
39+
40+
41+
private static MethodTree findMethod(ClassTree clazz, String name) {
42+
var method = clazz.methods().stream()
43+
.filter(f -> f.rawNode().name.equals(name))
44+
.findFirst().get();
45+
return method;
46+
}
47+
48+
49+
private ClassTree loadClass(String Name) {
50+
return ClassTree.fromBytes(bytes.getBytes(Name).get());
51+
}
52+
}
53+
54+
interface Foo {
55+
void foo();
56+
}
57+
58+
abstract class Bar {
59+
60+
public abstract void foo();
61+
62+
void bar() {
63+
64+
}
65+
66+
private void cantSeeMe() {
67+
68+
}
69+
}

pitest/src/main/java/org/pitest/mutationtest/engine/gregor/mutators/NullMutateEverything.java

Lines changed: 134 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Arrays;
44
import java.util.List;
55

6+
import org.objectweb.asm.AnnotationVisitor;
67
import org.objectweb.asm.Handle;
78
import org.objectweb.asm.Label;
89
import org.objectweb.asm.MethodVisitor;
@@ -15,143 +16,149 @@
1516
/**
1617
* Creates "mutants" that contain no changes at all possible mutation
1718
* points.
18-
*
19+
* <p>
1920
* Intended for testing purposes only.
20-
*
2121
*/
2222
public class NullMutateEverything implements MethodMutatorFactory {
2323

24-
@Override
25-
public MethodVisitor create(MutationContext context, MethodInfo methodInfo,
26-
MethodVisitor methodVisitor) {
27-
return new MutateEveryThing(this, context, methodVisitor);
28-
}
24+
public static List<MethodMutatorFactory> asList() {
25+
return Arrays.asList(new NullMutateEverything());
26+
}
2927

30-
@Override
31-
public String getGloballyUniqueId() {
32-
return "mutateallthethings";
33-
}
28+
@Override
29+
public MethodVisitor create(MutationContext context, MethodInfo methodInfo,
30+
MethodVisitor methodVisitor) {
31+
return new MutateEveryThing(this, context, methodVisitor);
32+
}
3433

35-
@Override
36-
public String getName() {
37-
return "mutateeverything";
38-
}
34+
@Override
35+
public String getGloballyUniqueId() {
36+
return "mutateallthethings";
37+
}
3938

40-
public static List<MethodMutatorFactory> asList() {
41-
return Arrays.asList(new NullMutateEverything());
42-
}
39+
@Override
40+
public String getName() {
41+
return "mutateeverything";
42+
}
4343

4444
}
4545

4646
class MutateEveryThing extends MethodVisitor {
47-
private final MethodMutatorFactory factory;
48-
private final MutationContext context;
49-
50-
MutateEveryThing(final MethodMutatorFactory factory,
51-
final MutationContext context,
52-
final MethodVisitor delegateMethodVisitor) {
53-
super(ASMVersion.ASM_VERSION, delegateMethodVisitor);
54-
this.factory = factory;
55-
this.context = context;
56-
}
57-
58-
@Override
59-
public void visitIincInsn(final int var, final int increment) {
60-
mutate("visitIincInsn");
61-
super.visitIincInsn(var, increment);
62-
}
63-
64-
@Override
65-
public void visitInsn(int opcode) {
66-
if (opcode != Opcodes.RETURN) {
67-
mutate("visitInsn", opcode);
68-
}
69-
super.visitInsn(opcode);
70-
}
71-
72-
@Override
73-
public void visitIntInsn(int opcode, int operand) {
74-
mutate("visitIntInsn", opcode);
75-
super.visitIntInsn(opcode,operand);
76-
}
77-
78-
@Override
79-
public void visitVarInsn(int opcode, int var) {
80-
mutate("visitVarInsn", opcode);
81-
super.visitVarInsn(opcode,var);
82-
}
83-
84-
@Override
85-
public void visitTypeInsn(int opcode, String type) {
86-
mutate("visitTypeInsn", opcode);
87-
super.visitTypeInsn(opcode, type);
88-
}
89-
90-
@Override
91-
public void visitFieldInsn(int opcode, String owner, String name,
92-
String desc) {
93-
mutate("visitFieldInsn", opcode);
94-
super.visitFieldInsn(opcode, owner, name, desc);
95-
}
96-
97-
@Override
98-
public void visitMethodInsn(int opcode, String owner, String name,
99-
String desc, boolean itf) {
100-
mutate("visitMethodInsn", opcode);
101-
super.visitMethodInsn(opcode, owner, name, desc, itf);
102-
}
103-
104-
@Override
105-
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
106-
Object... bsmArgs) {
107-
mutate("visitInvokeDynamicInsn");
108-
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
109-
}
110-
111-
@Override
112-
public void visitJumpInsn(int opcode, Label label) {
113-
mutate("visitJumpInsn", opcode);
114-
super.visitJumpInsn(opcode, label);
115-
}
116-
117-
@Override
118-
public void visitLdcInsn(Object cst) {
119-
mutate("visitLdcInsn");
120-
super.visitLdcInsn(cst);
121-
}
122-
123-
@Override
124-
public void visitTableSwitchInsn(int min, int max, Label dflt,
125-
Label... labels) {
126-
mutate("visitTableSwitchInsn");
127-
super.visitTableSwitchInsn(min, max, dflt, labels);
128-
}
129-
130-
@Override
131-
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
132-
mutate("visitLookupSwitchInsn");
133-
super.visitLookupSwitchInsn(dflt, keys, labels);
134-
}
135-
136-
@Override
137-
public void visitMultiANewArrayInsn(String desc, int dims) {
138-
mutate("visitMultiANewArrayInsn");
139-
super.visitMultiANewArrayInsn(desc, dims);
140-
}
141-
142-
@Override
143-
public void visitTryCatchBlock(Label start, Label end, Label handler,
144-
String type) {
145-
// Can't mutate try catch blocks as they are not modelled as an instruction in ASM
146-
super.visitTryCatchBlock(start, end, handler, type);
147-
}
148-
149-
private void mutate(String string, int opcode) {
150-
mutate("Null mutation in " + string + " with " + opcode);
151-
}
152-
153-
private void mutate(String string) {
154-
this.context.registerMutation(this.factory, string);
155-
}
47+
private final MethodMutatorFactory factory;
48+
private final MutationContext context;
49+
50+
MutateEveryThing(final MethodMutatorFactory factory,
51+
final MutationContext context,
52+
final MethodVisitor delegateMethodVisitor) {
53+
super(ASMVersion.ASM_VERSION, delegateMethodVisitor);
54+
this.factory = factory;
55+
this.context = context;
56+
}
57+
58+
@Override
59+
public void visitIincInsn(final int var, final int increment) {
60+
mutate("visitIincInsn");
61+
super.visitIincInsn(var, increment);
62+
}
63+
64+
@Override
65+
public void visitInsn(int opcode) {
66+
if (opcode != Opcodes.RETURN) {
67+
mutate("visitInsn", opcode);
68+
}
69+
super.visitInsn(opcode);
70+
}
71+
72+
@Override
73+
public void visitIntInsn(int opcode, int operand) {
74+
mutate("visitIntInsn", opcode);
75+
super.visitIntInsn(opcode, operand);
76+
}
77+
78+
@Override
79+
public void visitVarInsn(int opcode, int var) {
80+
mutate("visitVarInsn", opcode);
81+
super.visitVarInsn(opcode, var);
82+
}
83+
84+
@Override
85+
public void visitTypeInsn(int opcode, String type) {
86+
mutate("visitTypeInsn", opcode);
87+
super.visitTypeInsn(opcode, type);
88+
}
89+
90+
@Override
91+
public void visitFieldInsn(int opcode, String owner, String name,
92+
String desc) {
93+
mutate("visitFieldInsn", opcode);
94+
super.visitFieldInsn(opcode, owner, name, desc);
95+
}
96+
97+
@Override
98+
public void visitMethodInsn(int opcode, String owner, String name,
99+
String desc, boolean itf) {
100+
mutate("visitMethodInsn", opcode);
101+
super.visitMethodInsn(opcode, owner, name, desc, itf);
102+
}
103+
104+
@Override
105+
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
106+
Object... bsmArgs) {
107+
mutate("visitInvokeDynamicInsn");
108+
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
109+
}
110+
111+
@Override
112+
public void visitJumpInsn(int opcode, Label label) {
113+
mutate("visitJumpInsn", opcode);
114+
super.visitJumpInsn(opcode, label);
115+
}
116+
117+
@Override
118+
public void visitLdcInsn(Object cst) {
119+
mutate("visitLdcInsn");
120+
super.visitLdcInsn(cst);
121+
}
122+
123+
@Override
124+
public void visitTableSwitchInsn(int min, int max, Label dflt,
125+
Label... labels) {
126+
mutate("visitTableSwitchInsn");
127+
super.visitTableSwitchInsn(min, max, dflt, labels);
128+
}
129+
130+
@Override
131+
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
132+
mutate("visitLookupSwitchInsn");
133+
super.visitLookupSwitchInsn(dflt, keys, labels);
134+
}
135+
136+
@Override
137+
public void visitMultiANewArrayInsn(String desc, int dims) {
138+
mutate("visitMultiANewArrayInsn");
139+
super.visitMultiANewArrayInsn(desc, dims);
140+
}
141+
142+
@Override
143+
public void visitTryCatchBlock(Label start, Label end, Label handler,
144+
String type) {
145+
// Can't mutate try catch blocks as they are not modelled as an instruction in ASM
146+
super.visitTryCatchBlock(start, end, handler, type);
147+
}
148+
149+
@Override
150+
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
151+
mutate("visitAnnotation_" + descriptor);
152+
return super.visitAnnotation(descriptor, visible);
153+
}
154+
155+
156+
private void mutate(String string, int opcode) {
157+
mutate("Null mutation in " + string + " with " + opcode);
158+
}
159+
160+
private void mutate(String string) {
161+
this.context.registerMutation(this.factory, string);
162+
}
156163

157164
}

0 commit comments

Comments
 (0)