Skip to content

Commit

Permalink
Add @SuppressModernizer
Browse files Browse the repository at this point in the history
  • Loading branch information
stevie400 committed Feb 1, 2019
1 parent 9af8ee0 commit ba80198
Show file tree
Hide file tree
Showing 22 changed files with 609 additions and 104 deletions.
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -66,6 +66,23 @@ documents all of these. The most commonly used flags:
* `-Dmodernizer.failOnViolations` - fail phase if violations detected, defaults to true
* `-Dmodernizer.skip` - skip plugin execution, defaults to false

Ignoring elements
-----------------

You can indicate that a violations with a class or method should be ignored by
the plugin by adding `@SuppressModernizer` to the element you'd like
to ignore and adding the following dependency to your pom:

```xml
<dependencies>
<dependency>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-annotations</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
```

References
----------
* [ASM](http://asm.ow2.org/) provides Java bytecode introspection which enables Modernizer's checks
Expand Down
30 changes: 30 additions & 0 deletions modernizer-maven-annotations/pom.xml
@@ -0,0 +1,30 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-parent</artifactId>
<version>1.8.0-SNAPSHOT</version>
</parent>

<artifactId>modernizer-maven-annotations</artifactId>

<build>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>checkstyle/checkstyle.xml</configLocation>
<headerLocation>checkstyle/copyright_header.txt</headerLocation>
</configuration>
<dependencies>
<dependency>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-policy</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,30 @@
/*
* Copyright 2014-2018 Andrew Gaul <andrew@gaul.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.gaul.modernizer_maven_annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.TYPE,
ElementType.METHOD,
})
public @interface SuppressModernizer {
}
119 changes: 119 additions & 0 deletions modernizer-maven-plugin/pom.xml
@@ -0,0 +1,119 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-parent</artifactId>
<version>1.8.0-SNAPSHOT</version>
</parent>

<artifactId>modernizer-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>

<name>Modernizer Maven Plugin</name>
<url>https://github.com/andrewgaul/modernizer-maven-plugin</url>
<description>Detect use of legacy APIs which modern Java versions supersede.</description>

<prerequisites>
<maven>3.0.5</maven>
</prerequisites>

<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.6.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-annotations</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>checkstyle/checkstyle.xml</configLocation>
<headerLocation>checkstyle/copyright_header.txt</headerLocation>
</configuration>
<dependencies>
<dependency>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-policy</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Expand Up @@ -16,24 +16,27 @@

package org.gaul.modernizer_maven_plugin;

import static org.gaul.modernizer_maven_plugin.Utils.ASM_API;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.w3c.dom.Document;
Expand All @@ -48,12 +51,14 @@ final class Modernizer {
private final Collection<String> exclusions;
private final Collection<Pattern> exclusionPatterns;
private final Collection<String> ignorePackages;
private final Set<String> ignoreClassNames;
private final Collection<Pattern> ignoreFullClassNamePatterns;

Modernizer(String javaVersion, Map<String, Violation> violations,
Collection<String> exclusions,
Collection<Pattern> exclusionPatterns,
Collection<String> ignorePackages,
Set<String> ignoreClassNames,
Collection<Pattern> ignoreClassNamePatterns) {
long version;
if (javaVersion.startsWith("1.")) {
Expand All @@ -67,6 +72,7 @@ final class Modernizer {
this.exclusions = Utils.createImmutableSet(exclusions);
this.exclusionPatterns = Utils.createImmutableSet(exclusionPatterns);
this.ignorePackages = Utils.createImmutableSet(ignorePackages);
this.ignoreClassNames = Utils.createImmutableSet(ignoreClassNames);
this.ignoreFullClassNamePatterns
= Utils.createImmutableSet(ignoreClassNamePatterns);
}
Expand All @@ -75,7 +81,7 @@ Collection<ViolationOccurrence> check(ClassReader classReader)
throws IOException {
ModernizerClassVisitor classVisitor = new ModernizerClassVisitor(
javaVersion, violations, exclusions, exclusionPatterns,
ignorePackages, ignoreFullClassNamePatterns);
ignorePackages, ignoreClassNames, ignoreFullClassNamePatterns);
classReader.accept(classVisitor, 0);
return classVisitor.getOccurrences();
}
Expand Down Expand Up @@ -125,6 +131,7 @@ final class ModernizerClassVisitor extends ClassVisitor {
private final Collection<String> exclusions;
private final Collection<Pattern> exclusionPatterns;
private final Collection<String> ignorePackages;
private final Set<String> ignoreClassNames;
private final Collection<Pattern> ignoreFullClassNamePatterns;
private final Collection<ViolationOccurrence> occurrences =
new ArrayList<ViolationOccurrence>();
Expand All @@ -135,14 +142,16 @@ final class ModernizerClassVisitor extends ClassVisitor {
Map<String, Violation> violations, Collection<String> exclusions,
Collection<Pattern> exclusionPatterns,
Collection<String> ignorePackages,
Set<String> ignoreClassNames,
Collection<Pattern> ignoreFullClassNamePatterns) {
super(Opcodes.ASM7);
super(ASM_API);
Utils.checkArgument(javaVersion >= 0);
this.javaVersion = javaVersion;
this.violations = Utils.checkNotNull(violations);
this.exclusions = Utils.checkNotNull(exclusions);
this.exclusionPatterns = Utils.checkNotNull(exclusionPatterns);
this.ignorePackages = Utils.checkNotNull(ignorePackages);
this.ignoreClassNames = Utils.checkNotNull(ignoreClassNames);
this.ignoreFullClassNamePatterns =
Utils.checkNotNull(ignoreFullClassNamePatterns);
}
Expand Down Expand Up @@ -172,11 +181,12 @@ public MethodVisitor visitMethod(int access, final String methodName,
String[] exceptions) {
MethodVisitor base = super.visitMethod(access, methodName,
methodDescriptor, methodSignature, exceptions);
MethodVisitor origVisitor = new MethodVisitor(Opcodes.ASM7, base) {
MethodVisitor origVisitor = new MethodVisitor(ASM_API, base) {
};
InstructionAdapter adapter = new InstructionAdapter(Opcodes.ASM7,
InstructionAdapter adapter = new InstructionAdapter(ASM_API,
origVisitor) {
private int lineNumber = -1;
private boolean methodSuppressed = false;

@Override
public void visitFieldInsn(int opcode, String owner, String name,
Expand All @@ -196,6 +206,9 @@ public void visitMethodInsn(int opcode, String owner, String name,
@Override
public AnnotationVisitor visitAnnotation(String desc,
boolean visible) {
methodSuppressed |= Type.getType(desc).getClassName()
.equals(SuppressModernizer.class.getName());

String name = Type.getType(desc).getInternalName();
Violation violation = violations.get(name);
checkToken(name, violation, name, lineNumber);
Expand All @@ -214,6 +227,21 @@ private void visitFieldOrMethod(String owner, String name,
public void visitLineNumber(int lineNumber, Label start) {
this.lineNumber = lineNumber;
}

private void checkToken(
String token,
Violation violation,
String name,
int lineNumber
) {
if (methodSuppressed) {
return;
} else {
ModernizerClassVisitor.this
.checkToken(token, violation, name, lineNumber);
}

}
};
return adapter;
}
Expand Down Expand Up @@ -242,6 +270,9 @@ private void checkToken(String token, Violation violation, String name,
}

private boolean ignoreClass() {
if (ignoreClassNames.contains(className)) {
return true;
}
for (Pattern pattern : ignoreFullClassNamePatterns) {
if (pattern.matcher(className).matches()) {
return true;
Expand Down
Expand Up @@ -218,9 +218,22 @@ public void execute() throws MojoExecutionException {
}
}

Set<String> ignoreClassNames = new HashSet<String>();
try {
ignoreClassNames.addAll(
SuppressModernizerAnnotationDetector.detect(outputDirectory));
if (includeTestClasses) {
ignoreClassNames.addAll(
SuppressModernizerAnnotationDetector.detect(
testOutputDirectory));
}
} catch (IOException e) {
throw new MojoExecutionException("Error reading suppressions", e);
}

modernizer = new Modernizer(javaVersion, allViolations, allExclusions,
allExclusionPatterns, ignorePackages,
allIgnoreFullClassNamePatterns);
ignoreClassNames, allIgnoreFullClassNamePatterns);

try {
long count = recurseFiles(outputDirectory);
Expand Down

0 comments on commit ba80198

Please sign in to comment.