Skip to content

Commit

Permalink
fix class check order to correctly recognize ignoring annotation (fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
xvik committed Nov 4, 2020
1 parent 1867984 commit f0c6c09
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,6 @@
* Fix inner/anonymous classes check order: enclosing class must be processed first
to correctly apply ignoring annotation (#25)

### 1.5.1 (2020-06-06)
* Update animalsniffer 1.16 -> 1.18 (support java > 8)

Expand Down
Expand Up @@ -15,6 +15,7 @@ import org.gradle.api.reporting.Reporting
import org.gradle.api.tasks.*
import org.gradle.internal.reflect.Instantiator
import org.gradle.util.ClosureBackedAction
import org.gradle.util.GUtil
import ru.vyarus.gradle.plugin.animalsniffer.report.AnimalSnifferReports
import ru.vyarus.gradle.plugin.animalsniffer.report.AnimalSnifferReportsImpl
import ru.vyarus.gradle.plugin.animalsniffer.report.ReportCollector
Expand Down Expand Up @@ -136,7 +137,7 @@ class AnimalSniffer extends SourceTask implements VerificationTask, Reporting<An
}

@Inject
CollectionCallbackActionDecorator getCallbackActionDecorator() {
CollectionCallbackActionDecorator getCallbackActionDecorator() {
throw new UnsupportedOperationException()
}

Expand All @@ -153,12 +154,15 @@ class AnimalSniffer extends SourceTask implements VerificationTask, Reporting<An
ant.taskdef(name: 'animalsniffer', classname: 'org.codehaus.mojo.animal_sniffer.ant.CheckSignatureTask')
ReportCollector collector = new ReportCollector(getSourcesDirs().srcDirs)
replaceBuildListener(project, collector)
String sortedPath = preparePath(getSource())
getAnimalsnifferSignatures().each { signature ->
try {
collector.contextSignature(signature.name)
ant.animalsniffer(signature: signature.absolutePath, classpath: getClasspath()?.asPath) {
// labda case (Some$$Lambda$1). Ant removes every odd $ in a row
path(path: getSource().asPath.replace('$$', '$$$'))
// the same as getSource().asPath, but have to apply sorting because otherwise
// enclosing class could be parsed after inlined and so ignoring annotation on enclosing class
// would be ignored (actually, this problem appears only on windows)
path(path: sortedPath)
getSourcesDirs().srcDirs.each {
sourcepath(path: it.absoluteFile)
}
Expand Down Expand Up @@ -233,4 +237,25 @@ class AnimalSniffer extends SourceTask implements VerificationTask, Reporting<An
}
}
}

@SuppressWarnings(['Indentation', 'UnnecessaryCollectCall', 'UnnecessarySubstring'])
private static String preparePath(FileTree source) {
int clsExtSize = '.class'.length()
String innerIndicator = '$'
List<String> sortedPath = source
.collect { it.toString() }
.toSorted { a, b ->
if (a.contains(innerIndicator) || b.contains(innerIndicator)) {
String a1 = a.substring(0, a.length() - clsExtSize) // - .class
String b1 = b.substring(0, b.length() - clsExtSize)
// trick is to compare names without extension, so inner class would
// become longer and go last automatically;
// compare: Some.class < Some$1.class, but Some > Some$1
return a1 <=> b1
}
return a <=> b
}
// lambda case (Some$$Lambda$1). Ant removes every odd $ in a row
return GUtil.asPath(sortedPath).replace('$$', '$$$')
}
}
Expand Up @@ -52,6 +52,44 @@ class AnnKitTest extends AbstractKitTest {
}


def "Check enclosing class annotation detection for inner class"() {
setup:
build """
plugins {
id 'java'
id 'ru.vyarus.animalsniffer'
}
animalsniffer {
ignoreFailures = true
}
repositories { mavenCentral()}
dependencies {
signature 'org.codehaus.mojo.signature:java16-sun:1.0@signature'
compile "org.codehaus.mojo:animal-sniffer-annotations:1.14"
}
"""
fileFromClasspath('src/main/java/ann/Sample.java', '/ru/vyarus/gradle/plugin/animalsniffer/java/ann4inner/Sample.java')
fileFromClasspath('src/main/java/ann/Sample2.java', '/ru/vyarus/gradle/plugin/animalsniffer/java/ann4inner/Sample2.java')
// debug()

when: "run task"
BuildResult result = run('check')

then: "task successful"
result.task(':check').outcome == TaskOutcome.SUCCESS

then: "found no violations"
!result.output.contains("AnimalSniffer violations were found")

then: "report correct"
File file = file('/build/reports/animalsniffer/main.text')
!file.exists()
}


def "Check custom annotation detection"() {
setup:
build """
Expand Down
@@ -0,0 +1,29 @@
package ann;

import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;

import java.nio.file.Paths;
import java.util.concurrent.Callable;

@IgnoreJRERequirement
public class Sample {

public static void main(String[] args) {
// method added in 1.7
Boolean.compare(true, true);
}

public String someth() throws Exception {
// this will compile as separate class file and animalsniffer check order would be important
// (enclosed class must be checked first to apply annotataion)
// https://github.com/xvik/gradle-animalsniffer-plugin/issues/25
return new Callable<String>() {
@Override
public String call() throws Exception {
// class added in 1.7
Paths.get("/tmp");
return "ok";
}
}.call();
}
}
@@ -0,0 +1,20 @@
package ann;

import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;

import java.nio.file.Paths;

@IgnoreJRERequirement
public class Sample2 {

public static void main(String[] args) {
// method added in 1.7
Boolean.compare(true, true);
}

public class Inner {
public void someth() {
// class added in 1.7
}
}
}

0 comments on commit f0c6c09

Please sign in to comment.