Skip to content

Commit

Permalink
Merge pull request #1124 from hcoles/bug/first_line
Browse files Browse the repository at this point in the history
do not treat lines in bridges and synthetic methods as code lines
  • Loading branch information
hcoles committed Dec 2, 2022
2 parents 70ac58f + 6805731 commit 88d52fe
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Read all about it at http://pitest.org

## Releases

## 1.10.1 (unreleased)

* #1124 Fix bug introduced in 1.10.0 where bridge methods treated as valid lines of code

## 1.10.0

* #1067 Improved Quarkus and Roboelectric support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
Expand Down Expand Up @@ -83,20 +84,28 @@ public ClassNode rawNode() {
}

public Set<Integer> codeLineNumbers() {
return methods().stream()
return realMethods()
.flatMap(m -> m.instructions().stream()
.filter(n -> n instanceof LineNumberNode)
.map(n -> ((LineNumberNode) n).line))
.collect(Collectors.toSet());
}

public int numberOfCodeLines() {
return (int) methods().stream()
return (int) realMethods()
.flatMap(m -> m.instructions().stream()
.filter(n -> n instanceof LineNumberNode))
.count();
}

/**
* Methods, excluding bridges and synthetics
*/
public Stream<MethodTree> realMethods() {
return methods().stream()
.filter(m -> !m.isSynthetic() && !m.isBridge());
}

public boolean isAbstract() {
return (this.rawNode.access & Opcodes.ACC_ABSTRACT) != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public boolean isSynthetic() {
return (this.rawNode.access & Opcodes.ACC_SYNTHETIC) != 0;
}

public boolean isBridge() {
return (this.rawNode.access & Opcodes.ACC_BRIDGE) != 0;
}

public boolean isPrivate() {
return (this.rawNode.access & Opcodes.ACC_PRIVATE) != 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.pitest.bytecode.analysis;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.function.Function;
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;

import org.junit.Test;
import org.pitest.classinfo.ClassByteArraySource;
Expand Down Expand Up @@ -57,7 +56,27 @@ public void shouldNotDetectCodeLineAtClassDeclarationsWhenClassHasNoDefaultConst
@Test
public void shouldNotRecordLineNumbersFromSyntheticBridgeMethods() {
ClassTree underTest = ClassTree.fromBytes(bytesFor(Bridge.HasBridgeMethod.class));
assertThat(underTest.codeLineNumbers()).doesNotContain(1);
assertThat(underTest.codeLineNumbers()).doesNotContain(24);
}

@Test
public void shouldNotIncludeBridgeMethodsInCodeLineCount() {
ClassTree underTest = ClassTree.fromBytes(bytesFor(Bridge.HasBridgeMethod.class));
assertThat(underTest.numberOfCodeLines()).isEqualTo(3);
}

@Test
public void realMethodsDoesNotIncludeBridgeMethods() {
ClassTree underTest = ClassTree.fromBytes(bytesFor(Bridge.HasBridgeMethod.class));
assertThat(underTest.realMethods()).hasSize(underTest.methods().size() - 1);
}

@Test
public void realMethodsDoesNotIncludeSynthetics() {
ClassTree underTest = ClassTree.fromBytes(bytesFor(ParseMe.class));
MethodTree method = underTest.methods().get(0);
method.rawNode().access |= ACC_SYNTHETIC;
assertThat(underTest.realMethods()).doesNotContain(method);
}

byte[] bytesFor(Class<?> clazz) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public T getT() {
}

public static class HasBridgeMethod extends A<String> {

HasBridgeMethod() {
// so we don't have an autogenerated init also on line 24
}

@Override
public String getT() {
return null;
Expand Down

0 comments on commit 88d52fe

Please sign in to comment.