mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Initial commit for error-prone-contrib
- The `pom.xml` needs to be cleaned up a lot. Ideally we split off parts of the PRP parent pom so that it can be reused. - Code style: maybe we should more closely follow the error-prone project by also using two-space indentation. This project could be an incubator for plugins contributed to EP. (It is for this reason also that I used Auto Service and JUnit.)
This commit is contained in:
806
error-prone-contrib/pom.xml
Normal file
806
error-prone-contrib/pom.xml
Normal file
@@ -0,0 +1,806 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.picnicinternational.errorprone-contrib</groupId>
|
||||
<artifactId>errorprone-contrib</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<name>Picnic Error Prone Contrib</name>
|
||||
<inceptionYear>2017</inceptionYear>
|
||||
<organization>
|
||||
<name>Picnic International</name>
|
||||
<url>https://www.picnic.nl</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>https://opensource.org/licenses/mit-license.php</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:PicnicSupermarket/error-prone-contrib.git</developerConnection>
|
||||
<url>https://github.com/PicnicSupermarket/error-prone-contrib</url>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
<system>Github</system>
|
||||
<url>https://github.com/PicnicSupermarket/error-prone-contrib/issues</url>
|
||||
</issueManagement>
|
||||
<ciManagement>
|
||||
<system>Travis CI</system>
|
||||
<url>https://travis-ci.com/PicnicSupermarket/error-prone-contrib</url>
|
||||
</ciManagement>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<version.checkstyle>8.3</version.checkstyle>
|
||||
<version.error-prone>2.1.2</version.error-prone>
|
||||
<version.extra-enforcer-rules>1.0-beta-6</version.extra-enforcer-rules>
|
||||
<version.javac>9-dev-r4023-3</version.javac>
|
||||
<version.javadoc>2.10.4</version.javadoc>
|
||||
<version.jdk>1.8</version.jdk>
|
||||
<version.maven>3.5.0</version.maven>
|
||||
<version.plexus-compiler>2.8.2</version.plexus-compiler>
|
||||
<version.slf4j>1.7.25</version.slf4j>
|
||||
<version.surefire>2.20.1</version.surefire>
|
||||
<!-- Our build system (Travis CI) provides a monotonically increasing
|
||||
build number. When building locally, this number is obviously absent.
|
||||
So we provide a default value. -->
|
||||
<build.number>LOCAL</build.number>
|
||||
<!-- Arguments to the JVMs forked by Surefire. The specification of
|
||||
this 'argLine' property instead of the definition of the 'argLine'
|
||||
configuration setting allows users or plugins to specify additional
|
||||
arguments. In particular, JaCoCo relies on this for the configuration
|
||||
of its Java agent. -->
|
||||
<argLine><!--
|
||||
The test JVMs are short-running. By disabling certain expensive JIT
|
||||
optimizations we actually speed up most tests. -->
|
||||
-XX:TieredStopAtLevel=1
|
||||
<!-- We cap memory usage. This is especially relevant on Travis CI,
|
||||
but locally this should also be more than enough. -->
|
||||
-Xmx512m
|
||||
<!-- This argument cannot be set through Surefire's
|
||||
'systemPropertyVariables' configuration setting. Setting the file
|
||||
encoding is necessary because forked unit test invocations
|
||||
otherwise use the environment's file encoding. -->
|
||||
-Dfile.encoding=${project.build.sourceEncoding}
|
||||
<!-- This argument *can* be set through Surefire's
|
||||
'systemPropertyVariables' configuration setting, but by placing it
|
||||
here it automatically also applies to the Failsafe plugin. On Unix
|
||||
systems we use a lower-quality source of randomness, so as to avoid
|
||||
potential slowdown of tests relying on java.security.SecureRandom.
|
||||
Note that it is not fatal for the file to not exist, so this
|
||||
setting is Windows-compatible. The '/./' syntax is no accident; see
|
||||
https://bugs.openjdk.java.net/browse/JDK-6202721 for details. -->
|
||||
-Djava.security.egd=file:/dev/./urandom
|
||||
<!-- On Mac OS X, running in headless mode prevents the forked JVMs
|
||||
from showing up in the dock and capturing window focus. -->
|
||||
-Djava.awt.headless=true
|
||||
<!-- When slf4j-test is used for the interception of log messages,
|
||||
we also want them to be logged. -->
|
||||
-Dslf4jtest.print.level=DEBUG
|
||||
<!-- XXX: EXPLAIN -->
|
||||
-Xbootclasspath/p:${settings.localRepository}/com/google/errorprone/javac/${version.javac}/javac-${version.javac}.jar
|
||||
</argLine>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service</artifactId>
|
||||
<version>1.0-rc3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
<exclusions>
|
||||
<!-- We're using `com.google.errorprone:javac` instead. -->
|
||||
<exclusion>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
<version>${version.javac}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>23.2-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>0.36</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>${version.checkstyle}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>extra-enforcer-rules</artifactId>
|
||||
<version>${version.extra-enforcer-rules}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${version.slf4j}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<!-- Turn on filtering by default for application properties. -->
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>**/application.properties</include>
|
||||
<include>**/config.env</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>**/application.properties</exclude>
|
||||
<exclude>**/config.env</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/docker</directory>
|
||||
<targetPath>${project.build.directory}</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.PicnicSupermarket</groupId>
|
||||
<artifactId>googleformatter-maven-plugin</artifactId>
|
||||
<version>1.0.6-picnic-1-gjf-3b7ec93449</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>format-sources</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>format</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- We enable but skip the plugin by default.
|
||||
This way `format.sh` can resolve its
|
||||
dependencies in order to determine the version
|
||||
of google-java-format used. Actual formatting
|
||||
is done through explicit invocation by
|
||||
`format.sh`. -->
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<style>AOSP</style>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.lewisd</groupId>
|
||||
<artifactId>lint-maven-plugin</artifactId>
|
||||
<version>0.0.11</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate-pom</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<rules>
|
||||
<excludes>
|
||||
<exclude>OSS*</exclude>
|
||||
</excludes>
|
||||
</rules>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>de.thetaphi</groupId>
|
||||
<artifactId>forbiddenapis</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>detect-forbidden-api-usage</id>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
<goal>testCheck</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<bundledSignatures>
|
||||
<bundledSignature>jdk-system-out</bundledSignature>
|
||||
</bundledSignatures>
|
||||
<!-- The plugin tries to load all supertypes of any
|
||||
class it analyzes. Some of those types may be absent
|
||||
from the compilation classpath, because the module that
|
||||
contains them has the `runtime` or `test` scope. When
|
||||
this happens, we don't want to fail the build. (The
|
||||
alternative is to declare all those dependencies
|
||||
`provided`, but we'd rather not do that.) -->
|
||||
<failOnMissingClasses>false</failOnMissingClasses>
|
||||
<targetVersion>${version.jdk}</targetVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-checkstyle</id>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<checkstyleRules>
|
||||
<!-- We only enable rules that are not enforced by
|
||||
error-prone or automatically corrected through
|
||||
application of google-java-format. -->
|
||||
<module name="Checker">
|
||||
<module name="UniqueProperties" />
|
||||
<module name="TreeWalker">
|
||||
<module name="AnnotationUseStyleCheck">
|
||||
<!-- XXX: Right now this check doesn't
|
||||
completely enforce the desired style.
|
||||
See https://github.com/checkstyle/checkstyle/issues/4972;
|
||||
we're looking for the proposed `compact
|
||||
= ALWAYS` and `singleArrayCurlies =
|
||||
NEVER` style. -->
|
||||
</module>
|
||||
<module name="DeclarationOrder">
|
||||
<!-- We don't enforce sorting fields by
|
||||
their visibility modifier, for two
|
||||
reasons:
|
||||
- During (class) initialization
|
||||
declaration order matters. Though the
|
||||
plugin does not warn about fields
|
||||
with obvious dependencies, its
|
||||
dependency analysis is necessarily
|
||||
incomplete; NPEs may result if some
|
||||
of its advice is followed.
|
||||
- Sometimes a field is annotated
|
||||
`@VisibleForTesting`. It may then be
|
||||
preferable not to reorder. The plugin
|
||||
does not current respect this
|
||||
annotation. -->
|
||||
<property name="ignoreModifiers" value="true" />
|
||||
</module>
|
||||
<module name="DefaultComesLast" />
|
||||
<module name="FinalClass" />
|
||||
<module name="IllegalImport">
|
||||
<!-- These packages are found in some
|
||||
of the dependencies declared above. -->
|
||||
<property name="illegalClasses" value="javax.xml.bind.DatatypeConverter" />
|
||||
<property name="illegalClasses" value="org.springframework.context.annotation.ComponentScan" />
|
||||
<property name="illegalPkgs" value="com.amazonaws.annotation" />
|
||||
<property name="illegalPkgs" value="com.beust.jcommander.internal" />
|
||||
<property name="illegalPkgs" value="com.newrelic.agent.deps" />
|
||||
<property name="illegalPkgs" value="jdk" />
|
||||
<property name="illegalPkgs" value="jersey.repackaged" />
|
||||
<property name="illegalPkgs" value="nl.jqno.equalsverifier.internal" />
|
||||
<property name="illegalPkgs" value="org.apache.commons.lang3">
|
||||
<!-- Please use Guava or a custom
|
||||
helper method instead. -->
|
||||
</property>
|
||||
<property name="illegalPkgs" value="org.mutabilitydetector.internal" />
|
||||
</module>
|
||||
<module name="IllegalImport">
|
||||
<!-- XXX: This config uses
|
||||
regexes so as to disallow static
|
||||
imports. Once `illegalClasses`
|
||||
disallows static imports by default,
|
||||
this config can be merged into the one
|
||||
above. See
|
||||
https://github.com/checkstyle/checkstyle/issues/4954. -->
|
||||
<property name="illegalClasses" value="org\.testng\.AssertJUnit(\..*?)?" />
|
||||
<property name="regexp" value="true" />
|
||||
</module>
|
||||
<module name="MutableException" />
|
||||
<module name="NeedBraces" />
|
||||
<module name="NoClone" />
|
||||
<module name="NoFinalizer" />
|
||||
<module name="ParameterAssignmentCheck" />
|
||||
<module name="RedundantModifier" />
|
||||
<module name="SimplifyBooleanExpression" />
|
||||
<module name="SimplifyBooleanReturn" />
|
||||
<module name="WriteTag">
|
||||
<property name="tag" value="@author" />
|
||||
<property name="tagFormat" value="\S" />
|
||||
<property name="tagSeverity" value="error" />
|
||||
<property name="severity" value="ignore" />
|
||||
</module>
|
||||
<module name="UnnecessaryParentheses" />
|
||||
<module name="UnusedImports">
|
||||
<!-- Error-prone also detects these,
|
||||
but (currently) doesn't warn about
|
||||
JavaDoc-only imports. -->
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
||||
</checkstyleRules>
|
||||
<excludes>**/data/schema/**/*</excludes>
|
||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
<!-- The plugin's "excludes" property accepts an Ant
|
||||
pattern, but does not match against the full path. So
|
||||
rather than explicitly excluding generated sources, we
|
||||
have to explicitly include "original" sources. -->
|
||||
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
|
||||
<testSourceDirectories>${project.build.testSourceDirectory}</testSourceDirectories>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>${version.checkstyle}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<!-- XXX: Here, we could pass
|
||||
-J-XX:TieredStopAtLevel=1, like we do for most
|
||||
other JVMs started during the build. But that
|
||||
doesn't seem to yield a noticable speedup. -->
|
||||
</compilerArgs>
|
||||
<maxmem>256m</maxmem>
|
||||
<parameters>true</parameters>
|
||||
<source>${version.jdk}</source>
|
||||
<target>${version.jdk}</target>
|
||||
<!-- Erroneously inverted logic... for details, see
|
||||
https://jira.codehaus.org/browse/MCOMPILER-209 -->
|
||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0-M1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>apply-enforcement-rules</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<rules>
|
||||
<banDuplicatePomDependencyVersions />
|
||||
<dependencyConvergence />
|
||||
<requireJavaVersion>
|
||||
<version>${version.jdk}</version>
|
||||
</requireJavaVersion>
|
||||
<requireMavenVersion>
|
||||
<version>${version.maven}</version>
|
||||
</requireMavenVersion>
|
||||
<requirePluginVersions />
|
||||
<requireSameVersionsReactor />
|
||||
<requireUpperBoundDeps />
|
||||
</rules>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>extra-enforcer-rules</artifactId>
|
||||
<version>${version.extra-enforcer-rules}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>create-test-jar</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<skipIfEmpty>true</skipIfEmpty>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Implementation-Title>${project.name}</Implementation-Title>
|
||||
<Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
|
||||
<Implementation-Version>${project.version}.${build.number}.${build.revision}</Implementation-Version>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${version.javadoc}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<delimiters>
|
||||
<delimiter>@</delimiter>
|
||||
</delimiters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-source-jar</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${version.surefire}</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<!-- Timing measurements indicate that it's not
|
||||
beneficial to perform method-level parallelization for
|
||||
unit tests. -->
|
||||
<parallel>classes</parallel>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
<threadCount>2</threadCount>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>determine-build-number</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<buildNumberPropertyName>build.revision</buildNumberPropertyName>
|
||||
<revisionOnScmFailure>UNKNOWN</revisionOnScmFailure>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>tidy-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>modernize</id>
|
||||
<phase>process-test-classes</phase>
|
||||
<goals>
|
||||
<goal>modernizer</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<javaVersion>${version.jdk}</javaVersion>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<!-- By default we verify various aspects of a module and the
|
||||
artifact(s) it produces. We define these in checks in a profile
|
||||
so that they can be disabled during development. -->
|
||||
<id>verify-project</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!verification.skip</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.lewisd</groupId>
|
||||
<artifactId>lint-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>de.thetaphi</groupId>
|
||||
<artifactId>forbiddenapis</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Werror</arg>
|
||||
<arg>-Xdoclint:reference</arg>
|
||||
<arg>-Xlint:all</arg>
|
||||
<!-- Some generated jOOQ code performs a
|
||||
redundant cast. Until that is resolved we
|
||||
suppress this warning. See
|
||||
https://github.com/jOOQ/jOOQ/issues/6705. -->
|
||||
<arg>-Xlint:-cast</arg>
|
||||
<!-- Some of the dependencies we pull in
|
||||
declare additional non-existent dependencies in
|
||||
their MANIFEST.MF file. Since we're using Maven
|
||||
this doesn't impact us. As such the resultant
|
||||
compiler warnings are irrelevant. -->
|
||||
<arg>-Xlint:-path</arg>
|
||||
<!-- The Immutables.org annotation processor
|
||||
does not handle all annotations present on the
|
||||
classpath, and javac complains about this. That
|
||||
doesn't make a lot of sense. From time to time
|
||||
we should review whether this issue has been
|
||||
resolved. -->
|
||||
<arg>-Xlint:-processing</arg>
|
||||
<!-- The JAXB-generated classes implement
|
||||
java.io.Serializable, yet do not declare the
|
||||
serialVersionUID field. Until that's solved, we
|
||||
cannot enable "serial" warnings. -->
|
||||
<arg>-Xlint:-serial</arg>
|
||||
<!-- We want to enable almost all error-prone
|
||||
bug pattern checkers, so we enable all and then
|
||||
selectively deactivate some. -->
|
||||
<arg>-XepAllDisabledChecksAsWarnings</arg>
|
||||
<!-- The JAXB-generated classes exhibit some
|
||||
error-prone bug patterns. Nothing we can do
|
||||
about that, so we simply tell error-prone not
|
||||
to warn about generated code. -->
|
||||
<arg>-XepDisableWarningsInGeneratedCode</arg>
|
||||
<!-- XXX: A whole bunch of JPA entities violate
|
||||
this pattern. Revisit this once we phased out
|
||||
Hibernate. See
|
||||
https://picnic.atlassian.net/browse/PRP-6035. -->
|
||||
<arg>-Xep:ConstructorInvokesOverridable:OFF</arg>
|
||||
<!-- See https://github.com/google/error-prone/issues/655. -->
|
||||
<arg>-Xep:ConstructorLeaksThis:OFF</arg>
|
||||
<!-- See https://github.com/google/error-prone/issues/708. -->
|
||||
<arg>-Xep:FieldMissingNullable:OFF</arg>
|
||||
<!-- Disabled for now, but TBD. -->
|
||||
<arg>-Xep:MethodCanBeStatic:OFF</arg>
|
||||
<!-- See https://github.com/google/error-prone/issues/723. -->
|
||||
<arg>-Xep:ReturnMissingNullable:OFF</arg>
|
||||
<!-- Deals with an Android-specific limitation
|
||||
not applicable to us. See also
|
||||
https://github.com/google/error-prone/issues/488. -->
|
||||
<arg>-Xep:StaticOrDefaultInterfaceMethod:OFF</arg>
|
||||
<!-- Interesting idea, but way too much work for now. -->
|
||||
<arg>-Xep:Var:OFF</arg>
|
||||
<!-- The following bug patterns by default have
|
||||
"SUGGESTION" severity. We raise them to the
|
||||
"WARNING" level. See also
|
||||
https://github.com/google/error-prone/issues/486. -->
|
||||
<arg>-Xep:ConstantField:WARN</arg>
|
||||
<arg>-Xep:EmptySetMultibindingContributions:WARN</arg>
|
||||
<arg>-Xep:MixedArrayDimensions:WARN</arg>
|
||||
<arg>-Xep:MultipleTopLevelClasses:WARN</arg>
|
||||
<arg>-Xep:MultipleUnaryOperatorsInMethodCall:WARN</arg>
|
||||
<arg>-Xep:MultiVariableDeclaration:WARN</arg>
|
||||
<arg>-Xep:PackageLocation:WARN</arg>
|
||||
<arg>-Xep:ParameterComment:WARN</arg>
|
||||
<arg>-Xep:ParameterNotNullable:WARN</arg>
|
||||
<arg>-Xep:PrivateConstructorForNoninstantiableModuleTest:WARN</arg>
|
||||
<arg>-Xep:RemoveUnusedImports:WARN</arg>
|
||||
<arg>-Xep:ThrowsUncheckedException:WARN</arg>
|
||||
<arg>-Xep:UngroupedOverloads:WARN</arg>
|
||||
<arg>-Xep:UnnecessarySetDefault:WARN</arg>
|
||||
<arg>-Xep:UnnecessaryStaticImport:WARN</arg>
|
||||
<arg>-Xep:UseBinds:WARN</arg>
|
||||
<arg>-Xep:WildcardImport:WARN</arg>
|
||||
</compilerArgs>
|
||||
<compilerId>javac-with-errorprone</compilerId>
|
||||
<forceJavacCompilerUse>true</forceJavacCompilerUse>
|
||||
<showWarnings>true</showWarnings>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-compiler-javac</artifactId>
|
||||
<version>${version.plexus-compiler}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-compiler-javac-errorprone</artifactId>
|
||||
<version>${version.plexus-compiler}</version>
|
||||
<!-- XXX: Drop this exclusion once we get rid
|
||||
of our error-prone fork. -->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>analyze-dependencies</id>
|
||||
<phase>process-test-classes</phase>
|
||||
<goals>
|
||||
<goal>analyze-dep-mgt</goal>
|
||||
<goal>analyze-duplicate</goal>
|
||||
<goal>analyze-only</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<failBuild>true</failBuild>
|
||||
<failOnWarning>true</failOnWarning>
|
||||
<ignoreDirect>false</ignoreDirect>
|
||||
<ignoreNonCompile>true</ignoreNonCompile>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.base.VerifyException;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.method.MethodMatchers.MethodClassMatcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.LambdaExpressionTree;
|
||||
import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.MethodType;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMemberReference;
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.CheckForNull;
|
||||
|
||||
// XXX: Add more documentation. Explain how this is useful in the face of refactoring to more specific types.
|
||||
// XXX: Change this checker's name?
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "PrimitiveComparison",
|
||||
summary =
|
||||
"Ensure invocations of `Comparator#comparing{,Double,Int,Long}` match the return type"
|
||||
+ " of the provided function",
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION
|
||||
)
|
||||
public class BoxingComparisonCheck extends BugChecker implements MethodInvocationTreeMatcher {
|
||||
private static final Matcher<ExpressionTree> STATIC_MATCH = getStaticTargetMatcher();
|
||||
private static final Matcher<ExpressionTree> INSTANCE_MATCH = getInstanceTargetMatcher();
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
boolean isStatic = STATIC_MATCH.matches(tree, state);
|
||||
if (!isStatic && !INSTANCE_MATCH.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Type potentiallyBoxedType = getPotentiallyBoxedReturnType(tree.getArguments().get(0));
|
||||
if (potentiallyBoxedType == null) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
String actualMethodName = ASTHelpers.getSymbol(tree).getSimpleName().toString();
|
||||
String preferredMethodName = getPreferredMethod(state, potentiallyBoxedType, isStatic);
|
||||
if (actualMethodName.equals(preferredMethodName)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Description.Builder description = buildDescription(tree);
|
||||
tryFix(description, tree, preferredMethodName);
|
||||
return description.build();
|
||||
}
|
||||
|
||||
private String getPreferredMethod(VisitorState state, Type cmpType, boolean isStatic) {
|
||||
Types types = state.getTypes();
|
||||
Symtab symtab = state.getSymtab();
|
||||
|
||||
if (types.isSubtype(cmpType, symtab.intType)) {
|
||||
return isStatic ? "comparingInt" : "thenComparingInt";
|
||||
}
|
||||
|
||||
if (types.isSubtype(cmpType, symtab.longType)) {
|
||||
return isStatic ? "comparingLong" : "thenComparingLong";
|
||||
}
|
||||
|
||||
if (types.isSubtype(cmpType, symtab.doubleType)) {
|
||||
return isStatic ? "comparingDouble" : "thenComparingDouble";
|
||||
}
|
||||
|
||||
return isStatic ? "comparing" : "thenComparing";
|
||||
}
|
||||
|
||||
@CheckForNull
|
||||
private Type getPotentiallyBoxedReturnType(ExpressionTree tree) {
|
||||
switch (tree.getKind()) {
|
||||
case LAMBDA_EXPRESSION:
|
||||
/* Return the lambda expression's actual return type. */
|
||||
return ASTHelpers.getType(((LambdaExpressionTree) tree).getBody());
|
||||
case MEMBER_REFERENCE:
|
||||
/* Return the method's declared return type. */
|
||||
// XXX: Very fragile. Do better.
|
||||
Type subType2 = ((JCMemberReference) tree).referentType;
|
||||
return ((MethodType) subType2).getReturnType();
|
||||
default:
|
||||
/* This appears to be a genuine `{,ToInt,ToLong,ToDouble}Function`. */
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void tryFix(
|
||||
Description.Builder description,
|
||||
MethodInvocationTree tree,
|
||||
String preferredMethodName) {
|
||||
ExpressionTree expr = tree.getMethodSelect();
|
||||
switch (expr.getKind()) {
|
||||
case IDENTIFIER:
|
||||
SuggestedFix.Builder fix = SuggestedFix.builder();
|
||||
fix.addStaticImport(
|
||||
java.util.Comparator.class.getName() + '.' + preferredMethodName);
|
||||
fix.replace(expr, preferredMethodName);
|
||||
description.addFix(fix.build());
|
||||
return;
|
||||
case MEMBER_SELECT:
|
||||
MemberSelectTree ms = (MemberSelectTree) tree.getMethodSelect();
|
||||
description.addFix(
|
||||
SuggestedFix.replace(ms, ms.getExpression() + "." + preferredMethodName));
|
||||
return;
|
||||
default:
|
||||
throw new VerifyException("Unexpected type of expression: " + expr.getKind());
|
||||
}
|
||||
}
|
||||
|
||||
private static Matcher<ExpressionTree> getStaticTargetMatcher() {
|
||||
MethodClassMatcher clazz = staticMethod().onClass(Comparator.class.getName());
|
||||
|
||||
return anyMatch(
|
||||
unaryMethod(clazz, "comparingInt", ToIntFunction.class),
|
||||
unaryMethod(clazz, "comparingLong", ToLongFunction.class),
|
||||
unaryMethod(clazz, "comparingDouble", ToDoubleFunction.class),
|
||||
unaryMethod(clazz, "comparing", Function.class));
|
||||
}
|
||||
|
||||
private static Matcher<ExpressionTree> getInstanceTargetMatcher() {
|
||||
MethodClassMatcher instance = instanceMethod().onDescendantOf(Comparator.class.getName());
|
||||
|
||||
return anyMatch(
|
||||
unaryMethod(instance, "thenComparingInt", ToIntFunction.class),
|
||||
unaryMethod(instance, "thenComparingLong", ToLongFunction.class),
|
||||
unaryMethod(instance, "thenComparingDouble", ToDoubleFunction.class),
|
||||
unaryMethod(instance, "thenComparing", Function.class));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("varargs")
|
||||
private static Matcher<ExpressionTree> anyMatch(Matcher<ExpressionTree>... matchers) {
|
||||
return (ExpressionTree t, VisitorState s) ->
|
||||
Stream.of(matchers).anyMatch(m -> m.matches(t, s));
|
||||
}
|
||||
|
||||
private static Matcher<ExpressionTree> unaryMethod(
|
||||
MethodClassMatcher classMatcher, String name, Class<?> paramType) {
|
||||
return classMatcher.named(name).withParameters(paramType.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
|
||||
// XXX: Disable until fixed.
|
||||
//@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "EmptyMethod",
|
||||
summary = "Empty method can likely be deleted",
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR
|
||||
)
|
||||
public final class EmptyMethodCheck extends BugChecker implements MethodTreeMatcher {
|
||||
// XXX: Restrict: only warn about:
|
||||
// - static methods
|
||||
// - methods that are provably not in an inheritance hierarchy.
|
||||
// - public methods in a Mockito test class.
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
if (tree.getBody() == null || !tree.getBody().getStatements().isEmpty()) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return buildDescription(tree).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,601 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import java.io.IOException;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class BoxingComparisonCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(BoxingComparisonCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new BoxingComparisonCheck(), getClass());
|
||||
|
||||
// XXX: There are no tests for multiple replacements within the same expression:
|
||||
// - Error Prone doesn't currently support this, it seems.
|
||||
// - The `BugCheckerRefactoringTestHelper` throws an exception in this case.
|
||||
// - During actual compilation only the first replacement is applied.
|
||||
// XXX: Can we perhaps work-around this by describing the fixes in reverse order?
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparing(o -> (byte) 0);",
|
||||
" cCmp.thenComparing(o -> (char) 0);",
|
||||
" sCmp.thenComparing(o -> (short) 0);",
|
||||
" iCmp.thenComparing(o -> 0);",
|
||||
" lCmp.thenComparing(o -> 0L);",
|
||||
" fCmp.thenComparing(o -> 0.0f);",
|
||||
" dCmp.thenComparing(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> 0.0);",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparingInt(o -> (byte) 0);",
|
||||
" cCmp.thenComparingInt(o -> (char) 0);",
|
||||
" sCmp.thenComparingInt(o -> (short) 0);",
|
||||
" iCmp.thenComparingInt(o -> 0);",
|
||||
" lCmp.thenComparingLong(o -> 0L);",
|
||||
" fCmp.thenComparingDouble(o -> 0.0f);",
|
||||
" dCmp.thenComparingDouble(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariants() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparingDouble(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" cCmp.thenComparingInt(o -> Character.valueOf((char) 0));",
|
||||
" sCmp.thenComparingInt(o -> Short.valueOf((short) 0));",
|
||||
" iCmp.thenComparingInt(o -> Integer.valueOf(0));",
|
||||
" lCmp.thenComparingLong(o -> Long.valueOf(0));",
|
||||
" fCmp.thenComparingDouble(o -> Float.valueOf(0));",
|
||||
" dCmp.thenComparingDouble(o -> Double.valueOf(0));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.java",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = Comparator.comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = Comparator.comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = Comparator.comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = Comparator.comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = Comparator.comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = Comparator.comparing(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" {",
|
||||
" bCmp.thenComparing(o -> Byte.valueOf((byte) 0));",
|
||||
" cCmp.thenComparing(o -> Character.valueOf((char) 0));",
|
||||
" sCmp.thenComparing(o -> Short.valueOf((short) 0));",
|
||||
" iCmp.thenComparing(o -> Integer.valueOf(0));",
|
||||
" lCmp.thenComparing(o -> Long.valueOf(0));",
|
||||
" fCmp.thenComparing(o -> Float.valueOf(0));",
|
||||
" dCmp.thenComparing(o -> Double.valueOf(0));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import static java.util.Comparator.comparing;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparing(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparing(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparing(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparing(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparing(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparing(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparing(o -> 0.0);",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.java",
|
||||
"import static java.util.Comparator.comparing;",
|
||||
"import static java.util.Comparator.comparingDouble;",
|
||||
"import static java.util.Comparator.comparingInt;",
|
||||
"import static java.util.Comparator.comparingLong;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> (byte) 0);",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> (char) 0);",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> (short) 0);",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> 0);",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> 0L);",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> 0.0f);",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> 0.0);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariantsUsingStaticImports() throws IOException {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Test.java",
|
||||
"import static java.util.Comparator.comparingDouble;",
|
||||
"import static java.util.Comparator.comparingInt;",
|
||||
"import static java.util.Comparator.comparingLong;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparingDouble(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/Test.java",
|
||||
"import static java.util.Comparator.comparing;",
|
||||
"import static java.util.Comparator.comparingDouble;",
|
||||
"import static java.util.Comparator.comparingInt;",
|
||||
"import static java.util.Comparator.comparingLong;",
|
||||
"",
|
||||
"import java.util.Comparator;",
|
||||
"class Test {",
|
||||
" Comparator<Object> bCmp = comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<Object> cCmp = comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<Object> sCmp = comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<Object> iCmp = comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<Object> lCmp = comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<Object> fCmp = comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<Object> dCmp = comparing(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
// The logic for `char` and `short` is exactly analogous to the `byte` case.
|
||||
@Test
|
||||
public void testByteComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(this::toPrimitive);",
|
||||
" Comparator.comparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(o -> (byte) 0);",
|
||||
" Comparator.comparing(o -> (byte) 0, cmp());",
|
||||
" Comparator.comparing(this::toBoxed);",
|
||||
" Comparator.comparing(this::toBoxed, cmp());",
|
||||
" Comparator.comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator.comparing(o -> Byte.valueOf((byte) 0), cmp());",
|
||||
" Comparator.comparing(toBoxed());",
|
||||
" Comparator.comparing(toBoxed(), cmp());",
|
||||
" Comparator.comparingInt(this::toPrimitive);",
|
||||
" Comparator.comparingInt(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingInt(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(o -> Byte.valueOf((byte) 0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> Byte.valueOf((byte) 0));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(this::toPrimitive);",
|
||||
" cmp().thenComparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(o -> (byte) 0);",
|
||||
" cmp().thenComparing(o -> (byte) 0, cmp());",
|
||||
" cmp().thenComparing(this::toBoxed);",
|
||||
" cmp().thenComparing(this::toBoxed, cmp());",
|
||||
" cmp().thenComparing(o -> Byte.valueOf((byte) 0));",
|
||||
" cmp().thenComparing(o -> Byte.valueOf((byte) 0), cmp());",
|
||||
" cmp().thenComparing(toBoxed());",
|
||||
" cmp().thenComparing(toBoxed(), cmp());",
|
||||
" cmp().thenComparingInt(this::toPrimitive);",
|
||||
" cmp().thenComparingInt(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingInt(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(o -> Byte.valueOf((byte) 0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> (byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> Byte.valueOf((byte) 0));",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private byte toPrimitive(Object o) { return 0; }",
|
||||
" private Byte toBoxed(Object o) { return 0; }",
|
||||
" private Function<Object, Byte> toBoxed() { return o -> 0; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToIntFunction;",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(this::toPrimitive);",
|
||||
" Comparator.comparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(o -> 0);",
|
||||
" Comparator.comparing(o -> 0, cmp());",
|
||||
" Comparator.comparing(this::toBoxed);",
|
||||
" Comparator.comparing(this::toBoxed, cmp());",
|
||||
" Comparator.comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator.comparing(o -> Integer.valueOf(0), cmp());",
|
||||
" Comparator.comparing(toBoxed());",
|
||||
" Comparator.comparing(toBoxed(), cmp());",
|
||||
" Comparator.comparingInt(this::toPrimitive);",
|
||||
" Comparator.comparingInt(o -> 0);",
|
||||
" Comparator.comparingInt(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingInt(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingInt(o -> Integer.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(o -> 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(o -> Integer.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> Integer.valueOf(0));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(this::toPrimitive);",
|
||||
" cmp().thenComparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(o -> 0);",
|
||||
" cmp().thenComparing(o -> 0, cmp());",
|
||||
" cmp().thenComparing(this::toBoxed);",
|
||||
" cmp().thenComparing(this::toBoxed, cmp());",
|
||||
" cmp().thenComparing(o -> Integer.valueOf(0));",
|
||||
" cmp().thenComparing(o -> Integer.valueOf(0), cmp());",
|
||||
" cmp().thenComparing(toBoxed());",
|
||||
" cmp().thenComparing(toBoxed(), cmp());",
|
||||
" cmp().thenComparingInt(this::toPrimitive);",
|
||||
" cmp().thenComparingInt(o -> 0);",
|
||||
" cmp().thenComparingInt(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingInt(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingInt(o -> Integer.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(o -> 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(o -> Integer.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> Integer.valueOf(0));",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private int toPrimitive(Object o) { return 0; }",
|
||||
" private Integer toBoxed(Object o) { return 0; }",
|
||||
" private Function<Object, Integer> toBoxed() { return o -> 0; }",
|
||||
" private ToIntFunction<Object> toPrimitive() { return o -> 0; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToLongFunction;",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(this::toPrimitive);",
|
||||
" Comparator.comparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(o -> 0L);",
|
||||
" Comparator.comparing(o -> 0L, cmp());",
|
||||
" Comparator.comparing(this::toBoxed);",
|
||||
" Comparator.comparing(this::toBoxed, cmp());",
|
||||
" Comparator.comparing(o -> Long.valueOf(0));",
|
||||
" Comparator.comparing(o -> Long.valueOf(0), cmp());",
|
||||
" Comparator.comparing(toBoxed());",
|
||||
" Comparator.comparing(toBoxed(), cmp());",
|
||||
" Comparator.comparingLong(this::toPrimitive);",
|
||||
" Comparator.comparingLong(o -> 0L);",
|
||||
" Comparator.comparingLong(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingLong(o -> Long.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> 0L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> Long.valueOf(0));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(this::toPrimitive);",
|
||||
" cmp().thenComparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(o -> 0L);",
|
||||
" cmp().thenComparing(o -> 0L, cmp());",
|
||||
" cmp().thenComparing(this::toBoxed);",
|
||||
" cmp().thenComparing(this::toBoxed, cmp());",
|
||||
" cmp().thenComparing(o -> Long.valueOf(0));",
|
||||
" cmp().thenComparing(o -> Long.valueOf(0), cmp());",
|
||||
" cmp().thenComparing(toBoxed());",
|
||||
" cmp().thenComparing(toBoxed(), cmp());",
|
||||
" cmp().thenComparingLong(this::toPrimitive);",
|
||||
" cmp().thenComparingLong(o -> 0L);",
|
||||
" cmp().thenComparingLong(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingLong(o -> Long.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toPrimitive);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> 0L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> Long.valueOf(0));",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private long toPrimitive(Object o) { return 0L; }",
|
||||
" private Long toBoxed(Object o) { return 0L; }",
|
||||
" private Function<Object, Long> toBoxed() { return o -> 0L; }",
|
||||
" private ToLongFunction<Object> toPrimitive() { return o -> 0L; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(this::toPrimitive);",
|
||||
" Comparator.comparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(o -> 0.0f);",
|
||||
" Comparator.comparing(o -> 0.0f, cmp());",
|
||||
" Comparator.comparing(this::toBoxed);",
|
||||
" Comparator.comparing(this::toBoxed, cmp());",
|
||||
" Comparator.comparing(o -> Float.valueOf(0));",
|
||||
" Comparator.comparing(o -> Float.valueOf(0), cmp());",
|
||||
" Comparator.comparing(toBoxed());",
|
||||
" Comparator.comparing(toBoxed(), cmp());",
|
||||
" Comparator.comparingDouble(this::toPrimitive);",
|
||||
" Comparator.comparingDouble(o -> 0.0f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> Float.valueOf(0));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(this::toPrimitive);",
|
||||
" cmp().thenComparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(o -> 0.0f);",
|
||||
" cmp().thenComparing(o -> 0.0f, cmp());",
|
||||
" cmp().thenComparing(this::toBoxed);",
|
||||
" cmp().thenComparing(this::toBoxed, cmp());",
|
||||
" cmp().thenComparing(o -> Float.valueOf(0));",
|
||||
" cmp().thenComparing(o -> Float.valueOf(0), cmp());",
|
||||
" cmp().thenComparing(toBoxed());",
|
||||
" cmp().thenComparing(toBoxed(), cmp());",
|
||||
" cmp().thenComparingDouble(this::toPrimitive);",
|
||||
" cmp().thenComparingDouble(o -> 0.0f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> Float.valueOf(0));",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private float toPrimitive(Object o) { return 0.0f; }",
|
||||
" private Float toBoxed(Object o) { return 0.0f; }",
|
||||
" private Function<Object, Float> toBoxed() { return o -> 0.0f; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"import java.util.function.ToDoubleFunction;",
|
||||
"class A {",
|
||||
" {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(this::toPrimitive);",
|
||||
" Comparator.comparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparing(o -> 0.0);",
|
||||
" Comparator.comparing(o -> 0.0, cmp());",
|
||||
" Comparator.comparing(this::toBoxed);",
|
||||
" Comparator.comparing(this::toBoxed, cmp());",
|
||||
" Comparator.comparing(o -> Double.valueOf(0));",
|
||||
" Comparator.comparing(o -> Double.valueOf(0), cmp());",
|
||||
" Comparator.comparing(toBoxed());",
|
||||
" Comparator.comparing(toBoxed(), cmp());",
|
||||
" Comparator.comparingDouble(this::toPrimitive);",
|
||||
" Comparator.comparingDouble(o -> 0.0);",
|
||||
" Comparator.comparingDouble(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Comparator.comparingDouble(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(this::toPrimitive);",
|
||||
" cmp().thenComparing(this::toPrimitive, cmp());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparing(o -> 0.0);",
|
||||
" cmp().thenComparing(o -> 0.0, cmp());",
|
||||
" cmp().thenComparing(this::toBoxed);",
|
||||
" cmp().thenComparing(this::toBoxed, cmp());",
|
||||
" cmp().thenComparing(o -> Double.valueOf(0));",
|
||||
" cmp().thenComparing(o -> Double.valueOf(0), cmp());",
|
||||
" cmp().thenComparing(toBoxed());",
|
||||
" cmp().thenComparing(toBoxed(), cmp());",
|
||||
" cmp().thenComparingDouble(this::toPrimitive);",
|
||||
" cmp().thenComparingDouble(o -> 0.0);",
|
||||
" cmp().thenComparingDouble(toPrimitive());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(this::toBoxed);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" cmp().thenComparingDouble(o -> Double.valueOf(0));",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private double toPrimitive(Object o) { return 0.0; }",
|
||||
" private Double toBoxed(Object o) { return 0.0; }",
|
||||
" private Function<Object, Double> toBoxed() { return o -> 0.0; }",
|
||||
" private ToDoubleFunction<Object> toPrimitive() { return o -> 0.0; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.Comparator;",
|
||||
"import java.util.function.Function;",
|
||||
"class A {",
|
||||
" {",
|
||||
" Comparator.comparing(String::valueOf);",
|
||||
" Comparator.comparing(String::valueOf, cmp());",
|
||||
" Comparator.comparing(o -> String.valueOf(o));",
|
||||
" Comparator.comparing(o -> String.valueOf(o), cmp());",
|
||||
" Comparator.comparing(toStr());",
|
||||
" Comparator.comparing(toStr(), cmp());",
|
||||
"",
|
||||
" cmp().thenComparing(String::valueOf);",
|
||||
" cmp().thenComparing(String::valueOf, cmp());",
|
||||
" cmp().thenComparing(o -> String.valueOf(o));",
|
||||
" cmp().thenComparing(o -> String.valueOf(o), cmp());",
|
||||
" cmp().thenComparing(toStr());",
|
||||
" cmp().thenComparing(toStr(), cmp());",
|
||||
" }",
|
||||
"",
|
||||
" private Comparator<Object> cmp() { return null; }",
|
||||
" private Function<Object, String> toStr() { return String::valueOf; }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.picnicinternational.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class EmptyMethodCheckTest {
|
||||
private final CompilationTestHelper testHelper =
|
||||
CompilationTestHelper.newInstance(EmptyMethodCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testNegative() {
|
||||
testHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"class A {",
|
||||
" Object m() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" void m2() {",
|
||||
" System.out.println(42);",
|
||||
" }",
|
||||
"",
|
||||
" interface F {",
|
||||
" void fun();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPositive() {
|
||||
testHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"class A {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void m() {}",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static void m2() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user