diff options
author | Jeff Gaston <jeffrygaston@google.com> | 2017-06-16 22:32:32 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-06-16 22:32:32 +0000 |
commit | 612756b6f243e250a93104aae170545dce9b8d49 (patch) | |
tree | 3c674f3b504791a3d4175b9d1b484481e61576c1 | |
parent | 4e915182f8527cd19c154df55eabcae0301c8e9f (diff) | |
parent | 1442ac24eb7197d486e967f7c4bbd78bd56b0a71 (diff) | |
download | jacoco-612756b6f243e250a93104aae170545dce9b8d49.tar.gz |
Add ClassnameMatcher in preparation to pass into Instrumenter for filtering am: bbe2e9a9b2 am: 99916bb64e am: 3969781f7e
am: 1442ac24eb
Change-Id: Idaf9214f456c6c3ca73fb10c926786b8d10b4713
8 files changed, 275 insertions, 30 deletions
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java index 2cb16fed..cbd6a62b 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java @@ -120,16 +120,14 @@ public class CoverageTransformer implements ClassFileTransformer { if (!inclNoLocationClasses && !hasSourceLocation(protectionDomain)) { return false; } - if (exclClassloader.matches(loader.getClass().getName())) { + if (exclClassloader.apply(loader.getClass().getName())) { return false; } } return !classname.startsWith(AGENT_PREFIX) && - - includes.matches(classname) && - - !excludes.matches(classname); + includes.apply(classname) && + !excludes.apply(classname); } /** diff --git a/org.jacoco.core.test/src/org/jacoco/core/matcher/IncludeExcludeMatcherTest.java b/org.jacoco.core.test/src/org/jacoco/core/matcher/IncludeExcludeMatcherTest.java new file mode 100644 index 00000000..e0268956 --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/matcher/IncludeExcludeMatcherTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jeffry Gaston - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.matcher; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class IncludeExcludeMatcherTest { + + @Test + public void testEmpty() { + assertTrue(new IncludeExcludeMatcher<String>().apply("includeMe")); + } + + @Test + public void testSingleExclude() { + IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>() + .exclude(new WildcardMatcher("excluded")); + assertTrue(matcher.apply("included")); + assertFalse(matcher.apply("excluded")); + } + + @Test + public void testMultipleExcludes() { + IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>().exclude( + new WildcardMatcher("excluded")) + .exclude(new WildcardMatcher("excluded2")); + assertTrue(matcher.apply("included")); + assertFalse(matcher.apply("excluded")); + assertFalse(matcher.apply("excluded2")); + } + + @Test + public void testSingleInclude() { + IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>() + .include(new WildcardMatcher("include me")); + assertTrue(matcher.apply("include me")); + assertFalse(matcher.apply("not me")); + } + + @Test + public void testIncludesAndExcludes() { + IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>() + .include(new WildcardMatcher("inclusion1")) + .include(new WildcardMatcher("me too")) + .exclude(new WildcardMatcher("not me")) + .exclude(new WildcardMatcher("nope")); + assertTrue(matcher.apply("inclusion1")); + assertTrue(matcher.apply("me too")); + assertFalse(matcher.apply("not me")); + assertFalse(matcher.apply("nope")); + assertFalse(matcher.apply("other")); + } + + @Test + public void testExcludedInclusion() { + IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>() + .include(new WildcardMatcher("a")) + .exclude(new WildcardMatcher("a")); + assertFalse(matcher.apply("a")); + assertFalse(matcher.apply("b")); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/matcher/WildcardMatcherTest.java b/org.jacoco.core.test/src/org/jacoco/core/matcher/WildcardMatcherTest.java index 0d0a9c0a..baf1dc2b 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/matcher/WildcardMatcherTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/matcher/WildcardMatcherTest.java @@ -20,53 +20,53 @@ public class WildcardMatcherTest { @Test public void testEmpty() { - assertTrue(new WildcardMatcher("").matches("")); - assertFalse(new WildcardMatcher("").matches("abc")); + assertTrue(new WildcardMatcher("").apply("")); + assertFalse(new WildcardMatcher("").apply("abc")); } @Test public void testExact() { - assertTrue(new WildcardMatcher("abc/def.txt").matches("abc/def.txt")); + assertTrue(new WildcardMatcher("abc/def.txt").apply("abc/def.txt")); } @Test public void testCaseSensitive() { - assertFalse(new WildcardMatcher("abcdef").matches("abcDef")); - assertFalse(new WildcardMatcher("ABCDEF").matches("AbCDEF")); + assertFalse(new WildcardMatcher("abcdef").apply("abcDef")); + assertFalse(new WildcardMatcher("ABCDEF").apply("AbCDEF")); } @Test public void testQuote() { - assertFalse(new WildcardMatcher("rst.xyz").matches("rstAxyz")); - assertTrue(new WildcardMatcher("(x)+").matches("(x)+")); + assertFalse(new WildcardMatcher("rst.xyz").apply("rstAxyz")); + assertTrue(new WildcardMatcher("(x)+").apply("(x)+")); } @Test public void testWildcards() { - assertTrue(new WildcardMatcher("*").matches("")); - assertTrue(new WildcardMatcher("*").matches("java/lang/Object")); - assertTrue(new WildcardMatcher("*Test").matches("jacoco/MatcherTest")); - assertTrue(new WildcardMatcher("Matcher*").matches("Matcher")); - assertTrue(new WildcardMatcher("Matcher*").matches("MatcherTest")); - assertTrue(new WildcardMatcher("a*b*a").matches("a-b-b-a")); - assertFalse(new WildcardMatcher("a*b*a").matches("alaska")); - assertTrue(new WildcardMatcher("Hello?orld").matches("HelloWorld")); - assertFalse(new WildcardMatcher("Hello?orld").matches("HelloWWWorld")); - assertTrue(new WildcardMatcher("?aco*").matches("jacoco")); + assertTrue(new WildcardMatcher("*").apply("")); + assertTrue(new WildcardMatcher("*").apply("java/lang/Object")); + assertTrue(new WildcardMatcher("*Test").apply("jacoco/MatcherTest")); + assertTrue(new WildcardMatcher("Matcher*").apply("Matcher")); + assertTrue(new WildcardMatcher("Matcher*").apply("MatcherTest")); + assertTrue(new WildcardMatcher("a*b*a").apply("a-b-b-a")); + assertFalse(new WildcardMatcher("a*b*a").apply("alaska")); + assertTrue(new WildcardMatcher("Hello?orld").apply("HelloWorld")); + assertFalse(new WildcardMatcher("Hello?orld").apply("HelloWWWorld")); + assertTrue(new WildcardMatcher("?aco*").apply("jacoco")); } @Test public void testMultiExpression() { - assertTrue(new WildcardMatcher("Hello:World").matches("World")); - assertTrue(new WildcardMatcher("Hello:World").matches("World")); - assertTrue(new WildcardMatcher("*Test:*Foo").matches("UnitTest")); + assertTrue(new WildcardMatcher("Hello:World").apply("World")); + assertTrue(new WildcardMatcher("Hello:World").apply("World")); + assertTrue(new WildcardMatcher("*Test:*Foo").apply("UnitTest")); } @Test public void testDollar() { - assertTrue(new WildcardMatcher("*$*").matches("java/util/Map$Entry")); + assertTrue(new WildcardMatcher("*$*").apply("java/util/Map$Entry")); assertTrue(new WildcardMatcher("*$$$*") - .matches("org/example/Enity$$$generated123")); + .apply("org/example/Enity$$$generated123")); } } diff --git a/org.jacoco.core/src/org/jacoco/core/matcher/ClassnameMatcher.java b/org.jacoco.core/src/org/jacoco/core/matcher/ClassnameMatcher.java new file mode 100644 index 00000000..939bd5fe --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/matcher/ClassnameMatcher.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jeffry Gaston - initial API and implementation + * + *******************************************************************************/ + +package org.jacoco.core.matcher; + +import java.util.List; + +import org.objectweb.asm.ClassReader; + +/** + * A ClassnameMatcher matches ClassReader objects based on their class name + */ +public class ClassnameMatcher implements Predicate<ClassReader> { + private IncludeExcludeMatcher<String> matcher = new IncludeExcludeMatcher<String>(); + + /** + * Includes the given pattern from the matches of this matcher + * @param pattern to include + * @return this object (for chaining) + */ + public ClassnameMatcher include(String pattern) { + matcher.include(new WildcardMatcher(pattern)); + return this; + } + + /** + * Adds the given patterns as inclusions for this matcher + * @param patterns patterns to include + * @return this object (for chaining) + */ + public ClassnameMatcher include(List<String> patterns) { + for (String pattern : patterns) { + include(pattern); + } + return this; + } + + /** + * As the given pattern as an exclusion for this matcher + * @param pattern pattern to exclude + * @return this object (for chaining) + */ + public ClassnameMatcher exclude(String pattern) { + matcher.exclude(new WildcardMatcher(pattern)); + return this; + } + + /** + * As the given patterns as exclusions for this matcher + * @param patterns patterns to include + * @return this object (for chaining) + */ + public ClassnameMatcher exclude(List<String> patterns) { + for (String pattern : patterns) { + exclude(pattern); + } + return this; + } + + + /** + * Tells whether this matcher matches this class reader + * @param classReader the reader to match + * @return whether this matcher matches + */ + @Override + public boolean apply(ClassReader classReader) { + return matcher.apply(classReader.getClassName().replaceAll("/", ".")); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/matcher/IncludeExcludeMatcher.java b/org.jacoco.core/src/org/jacoco/core/matcher/IncludeExcludeMatcher.java new file mode 100644 index 00000000..50f1d886 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/matcher/IncludeExcludeMatcher.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jeffry Gaston - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.matcher; + +import java.util.ArrayList; +import java.util.List; + +/** + * An IncludeExcludeMatcher matches a given input if + * at least one inclusion matches and no exclusions match. + */ +public class IncludeExcludeMatcher<T> implements Predicate<T> { + private List<Predicate<T>> inclusions = new ArrayList<Predicate<T>>(); + private List<Predicate<T>> exclusions = new ArrayList<Predicate<T>>(); + + /** + * Includes the given matcher + * @param inclusion new matcher to include + * @return this object (for chaining several calls) + */ + public IncludeExcludeMatcher include(Predicate<T> inclusion) { + inclusions.add(inclusion); + return this; + } + + /** + * Excludes a given matcher + * @param exclusion + * @return this object (for chaining several calls) + */ + public IncludeExcludeMatcher exclude(Predicate<T> exclusion) { + exclusions.add(exclusion); + return this; + } + + /** + * Tells whether this matcher matches this string + * @param input the string match + * @return whether the matcher matches + */ + @Override + public boolean apply(T input) { + // doesn't match if an exclusion matches + for (Predicate<T> exclusion : exclusions) { + if (exclusion.apply(input)) { + return false; + } + } + // does match if an inclusion matches + for (Predicate<T> inclusion : inclusions) { + if (inclusion.apply(input)) { + return true; + } + } + // no match; choose a default based on whether any includes were given + return (inclusions.size() == 0); + } +} diff --git a/org.jacoco.core/src/org/jacoco/core/matcher/Predicate.java b/org.jacoco.core/src/org/jacoco/core/matcher/Predicate.java new file mode 100644 index 00000000..14d084b1 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/matcher/Predicate.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jeffry Gaston - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.matcher; + +/** + * A simple interface telling whether a predicate matches an input. + * Once the minimum supported version of Java is Java 1.8, then this can be replaced with the + * built-in Java predicate. + * While it could work to add a dependency on a library providing a similar interface, we prefer + * to keep the number of dependencies low, to avoid forcing other dependencies onto + * any builds that depend on Jacoco. + */ +public interface Predicate<T> { + boolean apply(final T s); +} diff --git a/org.jacoco.core/src/org/jacoco/core/matcher/WildcardMatcher.java b/org.jacoco.core/src/org/jacoco/core/matcher/WildcardMatcher.java index 9e7bd871..6ae20c4f 100644 --- a/org.jacoco.core/src/org/jacoco/core/matcher/WildcardMatcher.java +++ b/org.jacoco.core/src/org/jacoco/core/matcher/WildcardMatcher.java @@ -18,7 +18,7 @@ import java.util.regex.Pattern; * Multiple expressions can be separated with a colon (:). In this case the * expression matches if at least one part matches. */ -public class WildcardMatcher { +public class WildcardMatcher implements Predicate<String> { private final Pattern pattern; @@ -67,7 +67,8 @@ public class WildcardMatcher { * string to test * @return <code>true</code>, if the expression matches */ - public boolean matches(final String s) { + @Override + public boolean apply(final String s) { return pattern.matcher(s).matches(); } diff --git a/org.jacoco.report/src/org/jacoco/report/check/Rule.java b/org.jacoco.report/src/org/jacoco/report/check/Rule.java index acf90586..f424e81f 100644 --- a/org.jacoco.report/src/org/jacoco/report/check/Rule.java +++ b/org.jacoco.report/src/org/jacoco/report/check/Rule.java @@ -116,7 +116,7 @@ public final class Rule { } boolean matches(final String name) { - return includesMatcher.matches(name) && !excludesMatcher.matches(name); + return includesMatcher.apply(name) && !excludesMatcher.apply(name); } } |