diff --git a/access-modifier-annotation/src/main/java/org/kohsuke/accmod/impl/RestrictedElement.java b/access-modifier-annotation/src/main/java/org/kohsuke/accmod/impl/RestrictedElement.java index db43fbb..8dd7adb 100644 --- a/access-modifier-annotation/src/main/java/org/kohsuke/accmod/impl/RestrictedElement.java +++ b/access-modifier-annotation/src/main/java/org/kohsuke/accmod/impl/RestrictedElement.java @@ -38,5 +38,13 @@ public interface RestrictedElement { */ boolean isInTheInspectedModule(); + /** + * Returns true if the given {@link Location} is actually in this. + * + * @param location the location to be tested. + * @return true if the given {@link Location} is actually in this. + */ + boolean isSameClass(Location location); + String toString(); } diff --git a/access-modifier-annotation/src/main/java/org/kohsuke/accmod/restrictions/DoNotUse.java b/access-modifier-annotation/src/main/java/org/kohsuke/accmod/restrictions/DoNotUse.java index d59054f..e055828 100644 --- a/access-modifier-annotation/src/main/java/org/kohsuke/accmod/restrictions/DoNotUse.java +++ b/access-modifier-annotation/src/main/java/org/kohsuke/accmod/restrictions/DoNotUse.java @@ -35,26 +35,44 @@ */ public class DoNotUse extends AccessRestriction { public void written(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } public void usedAsSuperType(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } public void usedAsInterface(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } public void instantiated(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } public void invoked(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } public void read(Location loc, RestrictedElement target, ErrorListener errorListener) { + if (target.isSameClass(loc)) { + return; + } error(loc,target,errorListener); } diff --git a/access-modifier-checker/pom.xml b/access-modifier-checker/pom.xml index 5c9cc85..b26e91a 100644 --- a/access-modifier-checker/pom.xml +++ b/access-modifier-checker/pom.xml @@ -14,7 +14,19 @@ junit junit - 3.8.1 + 4.12 + test + + + org.mockito + mockito-core + 2.2.15 + test + + + org.assertj + assertj-core + 3.4.1 test diff --git a/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Checker.java b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Checker.java index 9365afe..bf36f1e 100644 --- a/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Checker.java +++ b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Checker.java @@ -176,13 +176,7 @@ public AnnotationVisitor visitAnnotation(String desc, boolean visible) { */ private AnnotationVisitor onAnnotationFor(final String keyName, String desc) { if (RESTRICTED_DESCRIPTOR.equals(desc)) { - RestrictedElement target = new RestrictedElement() { - public boolean isInTheInspectedModule() { - return isInTheInspectedModule; - } - - public String toString() { return keyName; } - }; + RestrictedElement target = new RestrictedElementImpl(isInTheInspectedModule, keyName); return new Parser(target) { @Override public void visitEnd() { diff --git a/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/RestrictedElementImpl.java b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/RestrictedElementImpl.java new file mode 100644 index 0000000..de1b802 --- /dev/null +++ b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/RestrictedElementImpl.java @@ -0,0 +1,39 @@ +package org.kohsuke.accmod.impl; + +public class RestrictedElementImpl implements RestrictedElement { + private final boolean isInTheInspectedModule; + private final String keyName; + + public RestrictedElementImpl(boolean isInTheInspectedModule, String keyName) { + this.isInTheInspectedModule = isInTheInspectedModule; + this.keyName = keyName; + } + + public boolean isInTheInspectedModule() { + return isInTheInspectedModule; + } + + @Override + public boolean isSameClass(Location location) { + String locationClassName = location.getClassName(); + if (locationClassName.contains("$")) { + locationClassName = locationClassName.split("\\$")[0]; + } + if(keyToClassName(keyName).equals(locationClassName)) { + return true; + } + return false; + } + + private static String keyToClassName(String key) { + if (key.contains(".")) { + key = key.split("\\.")[0]; + } + return key.replace('/', '.'); + } + + + public String toString() { + return keyName; + } +} diff --git a/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Restrictions.java b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Restrictions.java index dd3489a..01ab6e3 100644 --- a/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Restrictions.java +++ b/access-modifier-checker/src/main/java/org/kohsuke/accmod/impl/Restrictions.java @@ -81,6 +81,12 @@ public void written(Location location, ErrorListener errorListener) { public static final Restrictions NONE = new Restrictions(new RestrictedElement() { public boolean isInTheInspectedModule() { return false; } + + @Override + public boolean isSameClass(Location location) { + return false; + } + public String toString() { return "NONE"; } }); diff --git a/access-modifier-checker/src/test/java/org.kohsuke.accmod.impl/RestrictedElementImplTest.java b/access-modifier-checker/src/test/java/org.kohsuke.accmod.impl/RestrictedElementImplTest.java new file mode 100644 index 0000000..a0b7c02 --- /dev/null +++ b/access-modifier-checker/src/test/java/org.kohsuke.accmod.impl/RestrictedElementImplTest.java @@ -0,0 +1,32 @@ +package org.kohsuke.accmod.impl; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RestrictedElementImplTest { + + @Test + public void basic() throws Exception { + + assertThat(new RestrictedElementImpl(false, "hudson/util/TimeUnit2") + .isSameClass(createLocation("hudson.util.TimeUnit2$4"))).isTrue(); + + assertThat(new RestrictedElementImpl(false, "hudson/util/TimeUnit2.someMethod();") + .isSameClass(createLocation("hudson.util.TimeUnit2$4"))).isTrue(); + + assertThat(new RestrictedElementImpl(false, "hudson/util/XStream2.addCriticalField(Ljava/lang/Class;Ljava/lang/String;)V") + .isSameClass(createLocation("jenkins.model.Jenkins"))).isFalse(); + + assertThat(new RestrictedElementImpl(false, "jenkins/model/Jenkins.expandVariablesForDirectory(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; ") + .isSameClass(createLocation("jenkins.model.Jenkins$DescriptorImpl"))).isTrue(); + } + + private Location createLocation(String value) { + Location location = mock(Location.class); + when(location.getClassName()).thenReturn(value); + return location; + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index d342fc6..71f43a0 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,10 @@ pom Extensible application-specific access modifiers for Java + + UTF-8 + + access-modifier-annotation access-modifier-checker