From 1fcb1077d037acd21b9238d9eb7a4e6b521d7fcf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Jul 2023 17:38:09 +0200 Subject: [PATCH 01/61] [core] Support loading classes from runtime images That's one missing piece to support running PMD on a different JRE than the one used for analyzing. For Java up to version 8, one can put lib/rt.jar on the auxclasspath. But since Java 9, the runtime classes are stored in runtime images, that need to be loaded through the jrt:/ file system. Since the jrt-URLs are not connected anymore to a specific runtime image, AsmSymbolResolver needs to use directly the streams instead of URLs. The ClasspathClassLoader is basically disabled to actually load classes for reflection (#loadClass). In PMD 7, we shouldn't use that anymore. See also https://openjdk.org/jeps/220 --- .../internal/util/ClasspathClassLoader.java | 160 ++++++++++++++---- .../util/ClasspathClassLoaderTest.java | 113 +++++++++++++ .../internal/asm/AsmSymbolResolver.java | 16 +- .../java/symbols/internal/asm/Classpath.java | 12 +- .../java/symbols/internal/asm/Loader.java | 23 +-- .../symbols/internal/asm/AsmLoaderTest.kt | 2 +- 6 files changed, 266 insertions(+), 60 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index 024542c01f..e30055650b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -7,14 +7,27 @@ package net.sourceforge.pmd.internal.util; import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UncheckedIOException; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.StringTokenizer; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -33,29 +46,37 @@ public class ClasspathClassLoader extends URLClassLoader { private static final Logger LOG = LoggerFactory.getLogger(ClasspathClassLoader.class); + private FileSystem fileSystem; + String javaHome; + private Map> packagesDirsToModules; + static { registerAsParallelCapable(); } public ClasspathClassLoader(List files, ClassLoader parent) throws IOException { - super(fileToURL(files), parent); + super(new URL[0], parent); + for (URL url : fileToURL(files)) { + addURL(url); + } } public ClasspathClassLoader(String classpath, ClassLoader parent) throws IOException { - super(initURLs(classpath), parent); + super(new URL[0], parent); + for (URL url : initURLs(classpath)) { + addURL(url); + } } - private static URL[] fileToURL(List files) throws IOException { - + private List fileToURL(List files) throws IOException { List urlList = new ArrayList<>(); - for (File f : files) { urlList.add(f.toURI().toURL()); } - return urlList.toArray(new URL[0]); + return urlList; } - private static URL[] initURLs(String classpath) { + private List initURLs(String classpath) { AssertionUtil.requireParamNotNull("classpath", classpath); final List urls = new ArrayList<>(); try { @@ -69,10 +90,10 @@ public class ClasspathClassLoader extends URLClassLoader { } catch (IOException e) { throw new IllegalArgumentException("Cannot prepend classpath " + classpath + "\n" + e.getMessage(), e); } - return urls.toArray(new URL[0]); + return urls; } - private static void addClasspathURLs(final List urls, final String classpath) throws MalformedURLException { + private void addClasspathURLs(final List urls, final String classpath) throws MalformedURLException { StringTokenizer toker = new StringTokenizer(classpath, File.pathSeparator); while (toker.hasMoreTokens()) { String token = toker.nextToken(); @@ -81,7 +102,7 @@ public class ClasspathClassLoader extends URLClassLoader { } } - private static void addFileURLs(List urls, URL fileURL) throws IOException { + private void addFileURLs(List urls, URL fileURL) throws IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(fileURL.openStream()))) { String line; while ((line = in.readLine()) != null) { @@ -95,9 +116,67 @@ public class ClasspathClassLoader extends URLClassLoader { } } - private static URL createURLFromPath(String path) throws MalformedURLException { - File file = new File(path); - return file.getAbsoluteFile().toURI().normalize().toURL(); + private URL createURLFromPath(String path) throws MalformedURLException { + Path filePath = Paths.get(path).toAbsolutePath(); + if (filePath.endsWith(Paths.get("lib", "jrt-fs.jar"))) { + initializeJrtFilesystem(filePath); + // don't add jrt-fs.jar to the normal aux classpath + return null; + } + + return filePath.toUri().normalize().toURL(); + } + + /** + * Initializes a Java Runtime Filesystem that will be used to load class files. + * This allows end users to provide in the aux classpath another Java Runtime version + * than the one used for executing PMD. + * + * @param filePath path to the file "lib/jrt-fs.jar" inside the java installation directory. + * @see JEP 220: Modular Run-Time Images + */ + private void initializeJrtFilesystem(Path filePath) { + try { + LOG.debug("Detect Java Runtime Filesystem Provider in {}", filePath); + + if (fileSystem != null) { + throw new IllegalStateException("There is already a jrt filesystem. Do you have multiple jrt-fs.jar files on the classpath?"); + } + + if (filePath.getNameCount() < 2) { + throw new IllegalArgumentException("Can't determine java home from " + filePath + " - please provide a complete path."); + } + + try (URLClassLoader loader = new URLClassLoader(new URL[] { filePath.toUri().toURL() })) { + Map env = new HashMap<>(); + // note: providing java.home here is crucial, so that the correct runtime image is loaded. + // the class loader is only used to provide an implementation of JrtFileSystemProvider, if the current + // Java runtime doesn't provide one (e.g. if running in Java 8). + this.javaHome = filePath.getParent().getParent().toString(); + env.put("java.home", javaHome); + LOG.debug("Creating jrt-fs with env {}", env); + fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), env, loader); + } + + packagesDirsToModules = new HashMap<>(); + Path packages = fileSystem.getPath("packages"); + try (Stream packagesStream = Files.list(packages)) { + packagesStream.forEach(p -> { + String packageName = p.getFileName().toString().replace('.', '/'); + try (Stream modulesStream = Files.list(p)) { + Set modules = modulesStream + .map(Path::getFileName) + .map(Path::toString) + .collect(Collectors.toSet()); + packagesDirsToModules.put(packageName, modules); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } } @Override @@ -105,7 +184,36 @@ public class ClasspathClassLoader extends URLClassLoader { return getClass().getSimpleName() + "[[" + StringUtils.join(getURLs(), ":") - + "] parent: " + getParent() + ']'; + + "] jrt-fs: " + javaHome + " parent: " + getParent() + ']'; + } + + @Override + public InputStream getResourceAsStream(String name) { + // always first search in jrt-fs, if available + if (fileSystem != null) { + String packageName = name.substring(0, name.lastIndexOf('/')); + Set moduleNames = packagesDirsToModules.get(packageName); + if (moduleNames != null) { + LOG.trace("Trying to find {} in jrt-fs with packageName={} and modules={}", + name, packageName, moduleNames); + + for (String moduleCandidate : moduleNames) { + Path candidate = fileSystem.getPath("modules", moduleCandidate, name); + if (Files.exists(candidate)) { + LOG.trace("Found {}", candidate); + try { + return Files.newInputStream(candidate); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + } + } + + // search in the other jars of the aux classpath. + // this will call this.getResource, which will do a child-first search, see below. + return super.getResourceAsStream(name); } @Override @@ -126,24 +234,14 @@ public class ClasspathClassLoader extends URLClassLoader { @Override protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - synchronized (getClassLoadingLock(name)) { - // First, check if the class has already been loaded - Class c = findLoadedClass(name); - if (c == null) { - try { - // checking local - c = findClass(name); - } catch (final ClassNotFoundException | SecurityException e) { - // checking parent - // This call to loadClass may eventually call findClass again, in case the parent doesn't find anything. - c = super.loadClass(name, resolve); - } - } + throw new IllegalStateException("This class loader shouldn't be used to load classes"); + } - if (resolve) { - resolveClass(c); - } - return c; + @Override + public void close() throws IOException { + if (fileSystem != null) { + fileSystem.close(); } + super.close(); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java new file mode 100644 index 0000000000..baa8fdbe27 --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java @@ -0,0 +1,113 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.internal.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class ClasspathClassLoaderTest { + @TempDir + private Path tempDir; + + @Test + void loadEmptyClasspathWithParent() throws IOException { + try (ClasspathClassLoader loader = new ClasspathClassLoader("", ClasspathClassLoader.class.getClassLoader())) { + try (InputStream resource = loader.getResourceAsStream("java/lang/Object.class")) { + assertNotNull(resource); + try (DataInputStream data = new DataInputStream(resource)) { + assertClassFile(data, Integer.valueOf(System.getProperty("java.specification.version"))); + } + } + } + } + + /** + * This test case just documents the current behavior: Eventually we load + * the class files from the system class loader, even if the auxclasspath + * is essentially empty. + */ + @Test + void loadEmptyClasspathNoParent() throws IOException { + try (ClasspathClassLoader loader = new ClasspathClassLoader("", null)) { + try (InputStream resource = loader.getResourceAsStream("java/lang/Object.class")) { + assertNotNull(resource); + try (DataInputStream data = new DataInputStream(resource)) { + assertClassFile(data, Integer.valueOf(System.getProperty("java.specification.version"))); + } + } + } + } + + @Test + void loadFromJar() throws IOException { + final String RESOURCE_NAME = "net/sourceforge/pmd/Sample.txt"; + final String TEST_CONTENT = "Test\n"; + + Path jarPath = tempDir.resolve("custom.jar"); + try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(jarPath))) { + out.putNextEntry(new ZipEntry(RESOURCE_NAME)); + out.write(TEST_CONTENT.getBytes(StandardCharsets.UTF_8)); + } + String classpath = jarPath.toString(); + + try (ClasspathClassLoader loader = new ClasspathClassLoader(classpath, null)) { + try (InputStream in = loader.getResourceAsStream(RESOURCE_NAME)) { + assertNotNull(in); + String s = IOUtil.readToString(in, StandardCharsets.UTF_8); + assertEquals(TEST_CONTENT, s); + } + } + } + + /** + * Verifies, that we load the class files from the runtime image of the correct java home. + * + *

+ * This test only runs, if you have a folder ${HOME}/openjdk17. + *

+ */ + @Test + void loadFromJava17() throws IOException { + Path java17Home = Paths.get(System.getProperty("user.home"), "openjdk17"); + assumeTrue(Files.isDirectory(java17Home), "Couldn't find java17 installation at " + java17Home); + + Path jrtfsPath = java17Home.resolve("lib/jrt-fs.jar"); + assertTrue(Files.isRegularFile(jrtfsPath), "java17 installation is incomplete. " + jrtfsPath + " not found!"); + String classPath = jrtfsPath.toString(); + + try (ClasspathClassLoader loader = new ClasspathClassLoader(classPath, null)) { + assertEquals(java17Home.toString(), loader.javaHome); + try (InputStream stream = loader.getResourceAsStream("java/lang/Object.class")) { + assertNotNull(stream); + try (DataInputStream data = new DataInputStream(stream)) { + assertClassFile(data, 17); + } + } + } + } + + private void assertClassFile(DataInputStream data, int javaVersion) throws IOException { + int magicNumber = data.readInt(); + assertEquals(0xcafebabe, magicNumber); + data.readUnsignedShort(); // minorVersion + int majorVersion = data.readUnsignedShort(); + assertEquals(44 + javaVersion, majorVersion); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java index 31b06c9884..8da87a9520 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.net.URL; +import java.io.InputStream; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -16,7 +16,7 @@ import org.objectweb.asm.Opcodes; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; import net.sourceforge.pmd.lang.java.symbols.internal.asm.Loader.FailedLoader; -import net.sourceforge.pmd.lang.java.symbols.internal.asm.Loader.UrlLoader; +import net.sourceforge.pmd.lang.java.symbols.internal.asm.Loader.StreamLoader; import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.util.AssertionUtil; @@ -53,12 +53,12 @@ public class AsmSymbolResolver implements SymbolResolver { String internalName = getInternalName(binaryName); ClassStub found = knownStubs.computeIfAbsent(internalName, iname -> { - @Nullable URL url = getUrlOfInternalName(iname); - if (url == null) { + @Nullable InputStream inputStream = getStreamOfInternalName(iname); + if (inputStream == null) { return failed; } - return new ClassStub(this, iname, new UrlLoader(url), ClassStub.UNKNOWN_ARITY); + return new ClassStub(this, iname, new StreamLoader(binaryName, inputStream), ClassStub.UNKNOWN_ARITY); }); if (!found.hasCanonicalName()) { @@ -84,7 +84,7 @@ public class AsmSymbolResolver implements SymbolResolver { } @Nullable - URL getUrlOfInternalName(String internalName) { + InputStream getStreamOfInternalName(String internalName) { return classLoader.findResource(internalName + ".class"); } @@ -105,8 +105,8 @@ public class AsmSymbolResolver implements SymbolResolver { if (prev != failed && prev != null) { return prev; } - @Nullable URL url = getUrlOfInternalName(iname); - Loader loader = url == null ? FailedLoader.INSTANCE : new UrlLoader(url); + @Nullable InputStream inputStream = getStreamOfInternalName(iname); + Loader loader = inputStream == null ? FailedLoader.INSTANCE : new StreamLoader(internalName, inputStream); return new ClassStub(this, iname, loader, observedArity); }); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Classpath.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Classpath.java index 0bdfa4e57b..b879b053fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Classpath.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Classpath.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.net.URL; +import java.io.InputStream; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; @@ -23,9 +23,9 @@ public interface Classpath { * * @param resourcePath Resource path, as described in {@link ClassLoader#getResource(String)} * - * @return A URL if the resource exists, otherwise null + * @return A InputStream if the resource exists, otherwise null */ - @Nullable URL findResource(String resourcePath); + @Nullable InputStream findResource(String resourcePath); // @@ -42,7 +42,7 @@ public interface Classpath { default Classpath delegateTo(Classpath c) { return path -> { - URL p = findResource(path); + InputStream p = findResource(path); if (p != null) { return p; } @@ -56,11 +56,11 @@ public interface Classpath { /** - * Returns a classpath instance that uses {@link ClassLoader#getResource(String)} + * Returns a classpath instance that uses {@link ClassLoader#getResourceAsStream(String)} * to find resources. */ static Classpath forClassLoader(ClassLoader classLoader) { - return classLoader::getResource; + return classLoader::getResourceAsStream; } static Classpath contextClasspath() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java index a44cc6bc03..8289601568 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; import java.io.IOException; import java.io.InputStream; -import java.net.URL; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -35,27 +34,23 @@ abstract class Loader { } - static class UrlLoader extends Loader { + static class StreamLoader extends Loader { + private final @NonNull String name; + private final @NonNull InputStream stream; - private final @NonNull URL url; - - UrlLoader(@NonNull URL url) { - assert url != null : "Null url"; - this.url = url; + StreamLoader(@NonNull String name, @NonNull InputStream stream) { + this.name = name; + this.stream = stream; } - @Override - @Nullable - InputStream getInputStream() throws IOException { - return url.openStream(); + @NonNull InputStream getInputStream() { + return stream; } @Override public String toString() { - return "(URL loader)"; + return "(StreamLoader for " + name + ")"; } } - - } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt index f0e6c7f76a..a89096feb6 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt @@ -38,7 +38,7 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ // access flags // method reference with static ctdecl & zero formal parameters (asInstanceMethod) - val contextClasspath = Classpath { Thread.currentThread().contextClassLoader.getResource(it) } + val contextClasspath = Classpath { Thread.currentThread().contextClassLoader.getResourceAsStream(it) } test("First ever ASM test") { From ec2882a4f3499e7ca0783b870f7991391ffe5eb3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Jul 2023 17:53:22 +0200 Subject: [PATCH 02/61] Fix StringIndexOutOfBoundsException for default packages --- .../sourceforge/pmd/internal/util/ClasspathClassLoader.java | 3 ++- .../pmd/internal/util/ClasspathClassLoaderTest.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index e30055650b..7d9fe0a274 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -191,7 +191,8 @@ public class ClasspathClassLoader extends URLClassLoader { public InputStream getResourceAsStream(String name) { // always first search in jrt-fs, if available if (fileSystem != null) { - String packageName = name.substring(0, name.lastIndexOf('/')); + int lastSlash = name.lastIndexOf('/'); + String packageName = name.substring(0, lastSlash != -1 ? lastSlash : 0); Set moduleNames = packagesDirsToModules.get(packageName); if (moduleNames != null) { LOG.trace("Trying to find {} in jrt-fs with packageName={} and modules={}", diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java index baa8fdbe27..718d941ea2 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.internal.util; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; @@ -100,6 +101,9 @@ class ClasspathClassLoaderTest { assertClassFile(data, 17); } } + + // should not fail for resources without a package + assertNull(loader.getResourceAsStream("ClassInDefaultPackage.class")); } } From 05668150b10b6d0eefd655141730ad417a14a91d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Jul 2023 17:55:49 +0200 Subject: [PATCH 03/61] [doc] Add a note for aux classpath missing doc --- docs/pages/pmd/languages/java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index 43463f0c74..8e57b8acff 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -56,7 +56,7 @@ The semantic analysis roughly works like so: 3. The last pass resolves the types of expressions, which performs overload resolution on method calls, and type inference. TODO describe -* why we need auxclasspath +* why we need auxclasspath, and how to put the java classes onto the auxclasspath (jre/lib/rt.jar or lib/jrt-fs.jar). * how disambiguation can fail ## Type and symbol APIs From c4df61d257e9398c9664c17f31a5e52585adc9cb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Jul 2023 18:04:18 +0200 Subject: [PATCH 04/61] [doc] Update release notes (#4628) [skip ci] --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index eed34e9a6c..1bfa778ea6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -45,6 +45,7 @@ The remaining section describes the complete release notes for 7.0.0. * [#4582](https://github.com/pmd/pmd/issues/4582): \[dist] Download link broken * core * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first + * [#4628](https://github.com/pmd/pmd/issues/4628): \[core] Support loading classes from java runtime images * apex-design * [#4596](https://github.com/pmd/pmd/issues/4596): \[apex] ExcessivePublicCount ignores properties * java @@ -383,6 +384,7 @@ See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html) * [#4425](https://github.com/pmd/pmd/pull/4425): \[core] Replace TextFile::pathId * [#4454](https://github.com/pmd/pmd/issues/4454): \[core] "Unknown option: '-min'" but is referenced in documentation * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first + * [#4628](https://github.com/pmd/pmd/issues/4628): \[core] Support loading classes from java runtime images * cli * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting From 644f85836b848c373f8c4dccdd7ebff9032f8e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 7 Jul 2023 16:31:36 +0200 Subject: [PATCH 05/61] Add close routines for class stubs --- .../sourceforge/pmd/internal/util/IOUtil.java | 29 ++++++++++----- .../java/internal/JavaLanguageProcessor.java | 8 +++++ .../pmd/lang/java/symbols/SymbolResolver.java | 36 +++++++++++++++++-- .../internal/asm/AsmSymbolResolver.java | 28 +++++++++++++++ .../java/symbols/internal/asm/ClassStub.java | 13 +++++++ .../java/symbols/internal/asm/Loader.java | 35 +++++++++++++++--- .../java/symbols/internal/asm/ParseLock.java | 10 ++++++ .../symbols/internal/ast/MapSymResolver.java | 6 ++++ .../pmd/lang/java/types/TypeSystem.java | 12 ++++++- .../pmd/lang/java/JavaParsingHelper.java | 11 ++++-- .../symbols/internal/asm/SigParserTest.kt | 9 +++-- .../lang/java/types/TestUtilitiesForTypes.kt | 8 +++-- 12 files changed, 180 insertions(+), 25 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java index 1fce3ef4c4..9ce4e38a08 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java @@ -161,15 +161,7 @@ public final class IOUtil { public static Exception closeAll(Collection closeables) { Exception composed = null; for (AutoCloseable it : closeables) { - try { - it.close(); - } catch (Exception e) { - if (composed == null) { - composed = e; - } else { - composed.addSuppressed(e); - } - } + composed = closeAndAccumulate(it, composed); } return composed; } @@ -195,12 +187,31 @@ public final class IOUtil { } + /** + * Close the given closeable. If it fails with an exception, + * either return that one or suppress it (if the parameter + * exception is already non-null). + */ + public static @Nullable Exception closeAndAccumulate(AutoCloseable closeable, @Nullable Exception pending) { + try { + closeable.close(); + } catch (Exception e) { + if (pending == null) { + return e; + } else { + pending.addSuppressed(e); + } + } + return pending; + } + // The following methods are taken from Apache Commons IO. // The dependency was removed from PMD 6 because it had a security issue, // and upgrading was not possible without upgrading to Java 8. // See https://github.com/pmd/pmd/pull/3968 // TODO PMD 7: consider bringing back commons-io and cleaning this class up. + public static void closeQuietly(Closeable closeable) { try { closeable.close(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java index c3729bae3c..535d4f5f88 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java @@ -121,7 +121,15 @@ public class JavaLanguageProcessor extends BatchLanguageProcessor stack = listOf(first, others); + @Override public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { for (SymbolResolver resolver : stack) { @@ -81,6 +83,34 @@ public interface SymbolResolver { } return null; } + + + @Override + public void close() throws Exception { + Exception e = IOUtil.closeAll(listOf(first, others)); + if (e != null) { + throw e; + } + } + }; + } + + + /** + * Return a resolver that delegates to the given resolver without closing it. + */ + static SymbolResolver closeShieldResolver(SymbolResolver resolver) { + return new SymbolResolver() { + @Override + public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { + return resolver.resolveClassFromBinaryName(binaryName); + } + + + @Override + public void close() { + // don't close the underlying resolver + } }; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java index 8da87a9520..b9204fe6b8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; +import java.io.Closeable; import java.io.InputStream; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -12,7 +13,10 @@ import java.util.concurrent.ConcurrentMap; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.objectweb.asm.Opcodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import net.sourceforge.pmd.internal.util.IOUtil; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; import net.sourceforge.pmd.lang.java.symbols.internal.asm.Loader.FailedLoader; @@ -25,6 +29,8 @@ import net.sourceforge.pmd.util.AssertionUtil; */ public class AsmSymbolResolver implements SymbolResolver { + private static final Logger LOG = LoggerFactory.getLogger(AsmSymbolResolver.class); + static final int ASM_API_V = Opcodes.ASM9; private final TypeSystem ts; @@ -38,6 +44,7 @@ public class AsmSymbolResolver implements SymbolResolver { * instead of caching failure cases separately. */ private final ClassStub failed; + private boolean closed = false; public AsmSymbolResolver(TypeSystem ts, Classpath classLoader) { this.ts = ts; @@ -49,6 +56,9 @@ public class AsmSymbolResolver implements SymbolResolver { @Override public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { AssertionUtil.requireParamNotNull("binaryName", binaryName); + if (closed) { + throw new IllegalStateException("Resolver closed: " + binaryName); + } String internalName = getInternalName(binaryName); @@ -110,4 +120,22 @@ public class AsmSymbolResolver implements SymbolResolver { return new ClassStub(this, iname, loader, observedArity); }); } + + + @Override + public void close() throws Exception { + closed = true; + Exception e = null; + for (ClassStub stub : knownStubs.values()) { + Closeable closeable = stub.getCloseable(); + if (closeable != null) { + LOG.trace("Closing stream for {}", stub); + e = IOUtil.closeAndAccumulate(closeable, e); + } + } + knownStubs.clear(); + if (e != null) { + throw e; + } + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index fe31977e30..f28964ea75 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -138,9 +139,21 @@ final class ClassStub implements JClassSymbol, AsmStub, AnnotationOwner { protected boolean postCondition() { return signature != null && enclosingInfo != null; } + + + @Override + public @Nullable Closeable getCloseable() { + return loader.getInputStream(); + } }; } + + /** Return the closeable, or null if no system resources need to be closed. */ + @Nullable Closeable getCloseable() { + return this.parseLock.getCloseable(); + } + @Override public AsmSymbolResolver getResolver() { return resolver; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java index 8289601568..516e55bc1a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java @@ -5,49 +5,74 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -abstract class Loader { +abstract class Loader implements Closeable { - @Nullable - abstract InputStream getInputStream() throws IOException; + /** + * Return an input stream that must be closed by the caller. + * This method can be called exactly once. Return null if + * the loader is failed, or if the stream has already been returned. + */ + abstract @Nullable InputStream getInputStream(); static class FailedLoader extends Loader { static final FailedLoader INSTANCE = new FailedLoader(); + @Override @Nullable InputStream getInputStream() { return null; } + @Override public String toString() { return "(failed loader)"; } + + @Override + public void close() throws IOException { + // do nothing + } } static class StreamLoader extends Loader { + private final @NonNull String name; - private final @NonNull InputStream stream; + private InputStream stream; StreamLoader(@NonNull String name, @NonNull InputStream stream) { this.name = name; this.stream = stream; } + @Override @NonNull InputStream getInputStream() { - return stream; + InputStream result = stream; + this.stream = null; // null out to avoid double close + return result; } + + @Override + public void close() throws IOException { + if (stream != null) { + stream.close(); + } + } + + @Override public String toString() { return "(StreamLoader for " + name + ")"; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index ed8b234168..b4997f1cb8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -4,6 +4,9 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; +import java.io.Closeable; + +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,6 +74,13 @@ abstract class ParseLock { return true; } + + public @Nullable Closeable getCloseable() { + // do nothing by default + return null; + } + + @Override public String toString() { return "ParseLock{status=" + status + '}'; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java index 3012ba9e17..65a33acb41 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java @@ -35,4 +35,10 @@ final class MapSymResolver implements SymbolResolver { public @Nullable JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName) { return byCanonicalName.get(canonicalName); } + + + @Override + public void close() throws Exception { + // nothing to do + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java index 788dc9ec94..e1f54a069b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java @@ -63,7 +63,7 @@ import net.sourceforge.pmd.util.CollectionUtil; * {@link JavaNode#getTypeSystem()}. */ @SuppressWarnings("PMD.CompareObjectsWithEquals") -public final class TypeSystem { +public final class TypeSystem implements AutoCloseable { /** * Top type of the reference type system. This is the type for the @@ -315,13 +315,23 @@ public final class TypeSystem { return Objects.requireNonNull(sym, "sym"); } + private @NonNull JPrimitiveType createPrimitive(PrimitiveTypeKind kind, Class box) { return new JPrimitiveType(this, kind, new RealPrimitiveSymbol(this, kind), getBootStrapSymbol(box), HashTreePSet.empty()); } + /** + * This should only be called once all files have been processed. + */ + @Override + public void close() throws Exception { + this.resolver.close(); + } + // type creation routines + /** * Returns the class symbol for the given reflected class. This asks * the classloader of this type system. Returns null if the parameter diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java index 4a16d064d5..079aa21cf2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java @@ -29,6 +29,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.JavaParser; import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; import net.sourceforge.pmd.lang.java.internal.JavaLanguageProcessor; +import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; +import net.sourceforge.pmd.lang.java.symbols.internal.asm.AsmSymbolResolver; +import net.sourceforge.pmd.lang.java.symbols.internal.asm.Classpath; import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.internal.infer.TypeInferenceLogger; import net.sourceforge.pmd.lang.java.types.internal.infer.TypeInferenceLogger.SimpleLogger; @@ -45,7 +48,11 @@ public class JavaParsingHelper extends BaseParsingHelper { + Classpath classpath = Classpath.forClassLoader(JavaParsingHelper.class.getClassLoader()); + AsmSymbolResolver symResolver = new AsmSymbolResolver(ts, classpath); + return SymbolResolver.closeShieldResolver(symResolver); + }); /** This runs all processing stages when parsing. */ public static final JavaParsingHelper DEFAULT = new JavaParsingHelper( @@ -68,7 +75,7 @@ public class JavaParsingHelper extends BaseParsingHelper JTypeMirror) { val ts = testTypeSystem - val parsed = ts.asmLoader.sigParser.parseFieldType(this, sig) + val parsed = ts.asmLoader!!.sigParser.parseFieldType(this, sig) parsed shouldBe TypeDslOf(ts).test() } private fun LexicalScope.shouldThrowWhenParsingType(sig: String, matcher: (InvalidTypeSignatureException)->Unit={}) { val ex = shouldThrow { val ts = testTypeSystem - ts.asmLoader.sigParser.parseFieldType(this, sig) + ts.asmLoader!!.sigParser.parseFieldType(this, sig) } matcher(ex) } @@ -66,7 +69,7 @@ private fun LexicalScope.shouldParseMethod( ) { val ts = testTypeSystem val mockStub = mock(ExecutableStub::class.java) - `when`(mockStub.sigParser()).thenReturn(ts.asmLoader.sigParser) + `when`(mockStub.sigParser()).thenReturn(ts.asmLoader!!.sigParser) `when`(mockStub.enclosingTypeParameterOwner).thenReturn(null) `when`(mockStub.typeSystem).thenReturn(ts) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt index 90482a9828..8b190878da 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt @@ -34,8 +34,12 @@ val javaParser: JavaParsingHelper = JavaParsingHelper.DEFAULT val testTypeSystem: TypeSystem get() = JavaParsingHelper.TEST_TYPE_SYSTEM -// bc the method is package private -val TypeSystem.asmLoader: AsmSymbolResolver get() = this.resolver as AsmSymbolResolver +/** + * This is here bc the method is package private. + * The resolver is not necessarily an AsmSymbolResolver so that's why + * the return type is nullable. + */ +val TypeSystem.asmLoader: AsmSymbolResolver? get() = this.resolver as? AsmSymbolResolver fun TypeSystem.lub(vararg us: JTypeMirror): JTypeMirror = lub(us.toList()) fun TypeSystem.glb(vararg us: JTypeMirror): JTypeMirror = glb(us.toList()) From 5355594b5109ac946316b596a10cffd8dcfb11ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 7 Jul 2023 17:19:08 +0200 Subject: [PATCH 06/61] Improve stats reporting --- .../internal/asm/AsmSymbolResolver.java | 21 +++++++++++++++++++ .../java/symbols/internal/asm/ClassStub.java | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java index b9204fe6b8..75dd21a858 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java @@ -126,13 +126,34 @@ public class AsmSymbolResolver implements SymbolResolver { public void close() throws Exception { closed = true; Exception e = null; + LOG.trace("Closing resolver with entries for {} stubs", knownStubs.size()); + int numParsed = 0; + int numClosed = 0; + int numFailed = 0; + int numFailedQueries = 0; for (ClassStub stub : knownStubs.values()) { Closeable closeable = stub.getCloseable(); if (closeable != null) { LOG.trace("Closing stream for {}", stub); e = IOUtil.closeAndAccumulate(closeable, e); + numClosed++; + } else if (stub == failed) { + // Note that failed queries may occur under normal circumstances. + // Eg package names may be queried just to figure + // out whether they're packages or classes. + numFailedQueries++; + } else if (!stub.isFailed()) { + numParsed++; + } else { + numFailed++; } } + LOG.trace("Of {} distinct queries to the classloader, {} queries failed, " + + "{} classes were found and parsed successfully, " + + "{} were found but failed parsing (!), " + + "{} were found but never parsed.", + knownStubs.size(), numFailedQueries, numParsed, numFailed, numClosed); + knownStubs.clear(); if (e != null) { throw e; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index f28964ea75..45f7a76b5e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -154,6 +154,10 @@ final class ClassStub implements JClassSymbol, AsmStub, AnnotationOwner { return this.parseLock.getCloseable(); } + boolean isFailed() { + return this.parseLock.isFailed(); + } + @Override public AsmSymbolResolver getResolver() { return resolver; From 310f68aa52a0a989434e33acf1a0fb564d1ca488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 26 Jul 2023 17:16:31 +0200 Subject: [PATCH 07/61] Fix line/col numbers in TokenMgrError Ref #4635 Col number of zero may happen when the error is reported on a newline. In the rest of PMD a newline is considered to sit at the last index of the previous line. So the index is now the first character of the next line, which is slightly wrong but that doesn't matter much. --- .../net/sourceforge/pmd/lang/ast/TokenMgrError.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java index d4115e77b3..3b6366fb45 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.ast; +import static java.lang.Math.max; + import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -31,8 +33,8 @@ public final class TokenMgrError extends FileAnalysisException { */ public TokenMgrError(int line, int column, @Nullable FileId filename, String message, @Nullable Throwable cause) { super(message, cause); - this.line = line; - this.column = column; + this.line = max(line, 1); + this.column = max(column, 1); if (filename != null) { super.setFileId(filename); } @@ -44,8 +46,8 @@ public final class TokenMgrError extends FileAnalysisException { @InternalApi public TokenMgrError(boolean eofSeen, String lexStateName, int errorLine, int errorColumn, String errorAfter, char curChar) { super(makeReason(eofSeen, lexStateName, errorAfter, curChar)); - line = errorLine; - column = errorColumn; + line = max(errorLine, 1); + column = max(errorColumn, 1); } public int getLine() { From a91e7f8310b6a2d300b224c6d5e30f4e7bba8e7c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Sep 2023 16:59:00 +0200 Subject: [PATCH 08/61] [core] Improve logging for CPD --- .../java/net/sourceforge/pmd/cli/CpdCliTest.java | 15 ++++++++++++++- .../pmd/lang/LanguageVersionDiscoverer.java | 7 +++++++ .../pmd/lang/document/FileCollector.java | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java index 8a9d4758de..b60b511d8e 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java @@ -87,6 +87,12 @@ class CpdCliTest extends BaseCliTest { result.checkStdErr(containsString("[main] INFO net.sourceforge.pmd.cli - Log level is at TRACE")); } + @Test + void debugLoggingShouldMentionLanguage() throws Exception { + final CliExecutionResult result = runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--debug"); + result.checkStdErr(containsString("Created new FileCollector with LanguageVersionDiscoverer(LanguageRegistry(java))")); + } + @Test void defaultLogging() throws Exception { CliExecutionResult result = runCliSuccessfully("--minimum-tokens", "340", "--dir", SRC_DIR); @@ -112,6 +118,13 @@ class CpdCliTest extends BaseCliTest { result.checkStdErr(containsString("Usage: pmd cpd")); } + @Test + void testWrongCliOptionResultsInErrorLogging() throws Exception { + // --ignore-identifiers doesn't take an argument anymore - it is interpreted as a file for inputPaths + final CliExecutionResult result = runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "false"); + result.checkStdErr(containsString("No such file false")); + } + @Test void testFindJavaDuplication() throws Exception { runCli(VIOLATIONS_FOUND, "--minimum-tokens", "7", "--dir", SRC_DIR) @@ -125,7 +138,7 @@ class CpdCliTest extends BaseCliTest { */ @Test void testIgnoreIdentifiers() throws Exception { - runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers") + runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "false", "--debug") .verify(result -> result.checkStdOut(containsString( "Found a 14 line (89 tokens) duplication" ))); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java index ad8fef10b8..b4e5920480 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java @@ -168,4 +168,11 @@ public class LanguageVersionDiscoverer { public void onlyRecognizeLanguages(LanguageRegistry lang) { this.languageRegistry = Objects.requireNonNull(lang); } + + @Override + public String toString() { + return "LanguageVersionDiscoverer(" + languageRegistry + + (forcedVersion != null ? ",forcedVersion=" + forcedVersion : "") + + ")"; + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 20ec3aff72..6cc0ff5006 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -70,6 +70,7 @@ public final class FileCollector implements AutoCloseable { this.discoverer = discoverer; this.reporter = reporter; this.outerFsPath = outerFsPath; + LOG.debug("Created new FileCollector with {}", discoverer); } public void setRecursive(boolean collectFilesRecursively) { From 428dce72e8b931439fad3f880b06d0d0b8f101ae Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Sep 2023 17:26:55 +0200 Subject: [PATCH 09/61] [doc] Clarify CPD CLI for --ignore-identifiers and such Fixes #4676 --- docs/pages/pmd/userdocs/cpd/cpd.md | 60 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 73b7368f1c..e099ebc8f2 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -57,6 +57,20 @@ the duplication. Here's a quick summary: Novice as much as advanced readers may want to [read on on Refactoring Guru](https://refactoring.guru/smells/duplicate-code) for more in-depth strategies, use cases and explanations. +### Finding more duplicates + +For some languages, additional options are supported. E.g. Java supports `--ignore-identifiers`. This has the +effect, that all identifiers are replaced with the same placeholder value before the comparing. This helps to +identify structurally identical code that only differs in naming (different class names, different method names, +different parameter names). + +There are other similar options: `--ignore-annotations`, `--ignore-literals`, `--ignore-literal-sequences`, +`--ignore-sequences`, `--ignore-usings`. + +Note that these options are *disabled* by default (e.g. identifiers are *not* replaced with the same placeholder +value). By default, CPD finds identical duplicates. Using these options, the found duplicates are not anymore +exactly identical. + ## CLI Usage ### CLI options reference @@ -109,19 +123,17 @@ for more in-depth strategies, use cases and explanations. %} {% include custom/cli_option_row.html options="--skip-duplicate-files" description="Ignore multiple copies of files of the same name and length in comparison." - default="false" %} {% include custom/cli_option_row.html options="--exclude" option_arg="path" description="Files to be excluded from the analysis" %} {% include custom/cli_option_row.html options="--non-recursive" - description="Don't scan subdirectories" - default="false" + description="Don't scan subdirectories. By default, subdirectories are considered." %} {% include custom/cli_option_row.html options="--skip-lexical-errors" - description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD" - default="false" + description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD. + By default, CPD analysis is stopped on the first error." %} {% include custom/cli_option_row.html options="--format,-f" option_arg="format" @@ -144,38 +156,37 @@ for more in-depth strategies, use cases and explanations. Disable this feature with `--no-fail-on-violation` to exit with 0 instead and just output the report." %} {% include custom/cli_option_row.html options="--ignore-literals" - description="Ignore number values and string contents when comparing text" - default="false" + description="Ignore literal values such as numbers and strings when comparing text. + By default, literals are not ignored." languages="Java" %} + {% include custom/cli_option_row.html options="--ignore-literal-sequences" + description="Ignore sequences of literals such as list initializers. + By default, such sequences of literals are not ignored." + languages="C#, C++, Lua" + %} {% include custom/cli_option_row.html options="--ignore-identifiers" - description="Ignore constant and variable names when comparing text" - default="false" + description="Ignore names of classes, methods, variables, constants, etc. when comparing text. + By default, identifier names are not ignored." languages="Java" %} {% include custom/cli_option_row.html options="--ignore-annotations" - description="Ignore language annotations (Java) or attributes (C#) when comparing text" - default="false" + description="Ignore language annotations (Java) or attributes (C#) when comparing text. + By default, annotations are not ignored." languages="C#, Java" %} - {% include custom/cli_option_row.html options="--ignore-literal-sequences" - description="Ignore sequences of literals (common e.g. in list initializers)" - default="false" - languages="C#, C++, Lua" - %} {% include custom/cli_option_row.html options="--ignore-sequences" - description="Ignore sequences of identifier and literals" - default="false" + description="Ignore sequences of identifier and literals. + By default, such sequences are not ignored." languages="C++" %} {% include custom/cli_option_row.html options="--ignore-usings" - description="Ignore `using` directives in C# when comparing text" - default="false" + description="Ignore `using` directives in C# when comparing text. + By default, using directives are not ignored." languages="C#" %} {% include custom/cli_option_row.html options="--no-skip-blocks" description="Do not skip code blocks matched by `--skip-blocks-pattern`" - default="false" languages="C++" %} {% include custom/cli_option_row.html options="--skip-blocks-pattern" @@ -220,6 +231,13 @@ You may wish to check sources that are stored in different directories: There is no limit to the number of `--dir`, you may add. +You may wish to ignore identifiers so that more duplications are found, that only differ in naming: + +{% include cli_example.html + id="ignore_identifiers" + linux="pmd cpd --minimum-tokens 100 --dir src/main/java --ignore-identifiers" + windows="pmd.bat cpd --minimum-tokens 100 --dir src\main\java --ignore-identifiers" %} + And if you're checking a C source tree with duplicate files in different architecture directories you can skip those using `--skip-duplicate-files`: From ed61460401df6f52d9c0c776d4acf276336ced59 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Sep 2023 17:30:14 +0200 Subject: [PATCH 10/61] [doc] Update release notes (#4676) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f4270a1420..543528fc11 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -58,6 +58,7 @@ The remaining section describes the complete release notes for 7.0.0. * [#4294](https://github.com/pmd/pmd/issues/4294): \[doc] Migration Guide for upgrading PMD 6 ➡️ 7 * [#4303](https://github.com/pmd/pmd/issues/4303): \[doc] Document new property framework * [#4521](https://github.com/pmd/pmd/issues/4521): \[doc] Website is not mobile friendly + * [#4676](https://github.com/pmd/pmd/issues/4676): \[doc] Clarify how CPD `--ignore-literals` and `--ignore-identifiers` work * apex-design * [#4596](https://github.com/pmd/pmd/issues/4596): \[apex] ExcessivePublicCount ignores properties * apex-security @@ -596,6 +597,7 @@ See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html) * [#4303](https://github.com/pmd/pmd/issues/4303): \[doc] Document new property framework * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * [#4521](https://github.com/pmd/pmd/issues/4521): \[doc] Website is not mobile friendly + * [#4676](https://github.com/pmd/pmd/issues/4676): \[doc] Clarify how CPD `--ignore-literals` and `--ignore-identifiers` work * testing * [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module * [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work From a281e3d518e826bc1726a7a3338e65fba37b0a5e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Sep 2023 17:31:19 +0200 Subject: [PATCH 11/61] Add @Scrates1 as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 83 ++++++++++++++------------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 04b834beb0..dc791f2b22 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7231,6 +7231,15 @@ "bug", "code" ] + }, + { + "login": "Scrates1", + "name": "Scrates1", + "avatar_url": "https://avatars.githubusercontent.com/u/49557842?v=4", + "profile": "https://github.com/Scrates1", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 8c79407044..f62a34406b 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -659,369 +659,370 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Satoshi Kubo

🐛
Scott Kennedy

🐛
Scott Wells

🐛 💻 -
Scrsloota

💻 +
Scrates1

🐛 +
Scrsloota

💻
Sebastian Bögl

🐛
Sebastian Schuberth

🐛
Sebastian Schwarz

🐛
Seren

🐛 💻
Sergey Gorbaty

🐛
Sergey Kozlov

🐛 -
Sergey Yanzin

💻 🐛 +
Sergey Yanzin

💻 🐛
Seth Wilcox

💻
Shubham

💻 🐛
Simon Abykov

💻 🐛
Simon Xiao

🐛
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛 -
Stanislav Myachenkov

💻 +
Stanislav Myachenkov

💻
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛
Stefan Klöss-Schuster

🐛
Stefan Wolf

🐛
Stephan H. Wissel

🐛 -
Stephen

🐛 +
Stephen

🐛
Stephen Friedrich

🐛
Steve Babula

💻
Steven Stearns

🐛 💻
Stexxe

🐛
Stian Lågstad

🐛
StuartClayton5

🐛 -
Supun Arunoda

🐛 +
Supun Arunoda

🐛
Suren Abrahamyan

🐛
Suvashri

📖
SwatiBGupta1110

🐛
SyedThoufich

🐛
Szymon Sasin

🐛
T-chuangxin

🐛 -
TERAI Atsuhiro

🐛 +
TERAI Atsuhiro

🐛
TIOBE Software

💻 🐛
Tarush Singh

💻
Taylor Smock

🐛
Techeira Damián

💻 🐛
Ted Husted

🐛
TehBakker

🐛 -
The Gitter Badger

🐛 +
The Gitter Badger

🐛
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛 -
ThrawnCA

🐛 +
ThrawnCA

🐛
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Copeland

🐛 💻 📖
Tom Daly

🐛
Tomer Figenblat

🐛 -
Tomi De Lucca

💻 🐛 +
Tomi De Lucca

💻 🐛
Torsten Kleiber

🐛
TrackerSB

🐛
Tyson Stewart

🐛
Ullrich Hafner

🐛
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛 -
Valeria

🐛 +
Valeria

🐛
Valery Yatsynovich

📖
Vasily Anisimov

🐛
Vibhor Goyal

🐛
Vickenty Fesunov

🐛
Victor Noël

🐛
Vincent Galloy

💻 -
Vincent HUYNH

🐛 +
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛
Vitaly

🐛
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛 -
Vsevolod Zholobov

🐛 +
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛
Wayne J. Earl

🐛
Wchenghui

🐛
Wener

💻 -
Will Winder

🐛 +
Will Winder

🐛
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛
XenoAmess

💻 🐛
Yang

💻 -
YaroslavTER

🐛 +
YaroslavTER

🐛
Yasar Shaikh

💻
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛
Yurii Dubinka

🐛
Zoltan Farkas

🐛 -
Zustin

🐛 +
Zustin

🐛
aaronhurst-google

🐛 💻
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛
anicoara

🐛
arunprasathav

🐛 -
asiercamara

🐛 +
asiercamara

🐛
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛
axelbarfod1

🐛
b-3-n

🐛 -
balbhadra9

🐛 +
balbhadra9

🐛
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛
caesarkim

🐛
carolyujing

🐛 -
cbfiddle

🐛 +
cbfiddle

🐛
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛
cristalp

🐛 -
crunsk

🐛 +
crunsk

🐛
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛 📖
d1ss0nanz

🐛
dague1

📖
dalizi007

💻 -
danbrycefairsailcom

🐛 +
danbrycefairsailcom

🐛
dariansanity

🐛
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛 -
dinesh150

🐛 +
dinesh150

🐛
diziaq

🐛
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛 -
ekkirala

🐛 +
ekkirala

🐛
emersonmoura

🐛
fairy

🐛
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛 -
freafrea

🐛 +
freafrea

🐛
fsapatin

🐛
gracia19

🐛
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛 -
hemanshu070

🐛 +
hemanshu070

🐛
henrik242

🐛
hongpuwu

🐛
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛 -
jakivey32

🐛 +
jakivey32

🐛
jbennett2091

🐛
jcamerin

🐛
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛 -
kabroxiko

💻 🐛 +
kabroxiko

💻 🐛
karwer

🐛
kaulonline

🐛
kdaemonv

🐛
kdebski85

🐛 💻
kenji21

💻 🐛
kfranic

🐛 -
khalidkh

🐛 +
khalidkh

🐛
koalalam

🐛
krzyk

🐛
lasselindqvist

🐛
lgemeinhardt

🐛
lihuaib

🐛
lonelyma1021

🐛 -
lpeddy

🐛 +
lpeddy

🐛
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛
matchbox

🐛
matthiaskraaz

🐛 -
meandonlyme

🐛 +
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mluckam

💻
mohan-chinnappan-n

💻
mriddell95

🐛
mrlzh

🐛 -
msloan

🐛 +
msloan

🐛
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛 -
nwcm

📖 +
nwcm

📖
oggboy

🐛
oinume

🐛
orimarko

💻 🐛
pacvz

💻
pallavi agarwal

🐛
parksungrin

🐛 -
patpatpat123

🐛 +
patpatpat123

🐛
patriksevallius

🐛
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛 -
prabhushrikant

🐛 +
prabhushrikant

🐛
pujitha8783

🐛
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛 -
reudismam

💻 🐛 +
reudismam

💻 🐛
rijkt

🐛
rillig-tk

🐛
rmohan20

💻 🐛
rnveach

🐛
rxmicro

🐛
ryan-gustafson

💻 🐛 -
sabi0

🐛 +
sabi0

🐛
scais

🐛
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛
shiomiyan

📖
simeonKondr

🐛 -
snajberk

🐛 +
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻
sratz

🐛
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛 -
suruchidawar

🐛 +
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛 -
tobwoerk

🐛 +
tobwoerk

🐛
tprouvot

🐛 💻
trentchilders

🐛
triandicAnt

🐛
trishul14

🐛
tsui

🐛
winhkey

🐛 -
witherspore

🐛 +
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛 -
xyf0921

🐛 +
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛 -
ztt79

🐛 +
ztt79

🐛
zzzzfeng

🐛
Árpád Magosányi

🐛
任贵杰

🐛 From 672afa95c03f87ac65267f6dc61cbe2a0602d04d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Sep 2023 18:36:25 +0200 Subject: [PATCH 12/61] [core] CLI - make sure positional inputPaths are not lost --- .../AbstractAnalysisPmdSubcommand.java | 27 +++++++++++-------- .../net/sourceforge/pmd/cli/CpdCliTest.java | 9 ++++++- .../commands/internal/BaseCommandTest.java | 3 ++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 758f0cb6c2..490c2b9af0 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -7,7 +7,6 @@ package net.sourceforge.pmd.cli.commands.internal; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; import net.sourceforge.pmd.AbstractConfiguration; @@ -34,6 +33,14 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths; + @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " + + "Equivalent to using --dir.") + // Note: we can't directly use inputPaths here, because "--dir" might be specified later in the + // command line. And PicoCli will then initialize the field inputPaths with a fresh empty List, replacing + // anything what was added before.So we need to combine the two lists in #validate() + private List positionalInputPaths; + + @Option(names = "--file-list", description = "Path to a file containing a list of files to analyze, one path per line. " @@ -50,16 +57,6 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths) { - if (this.inputPaths == null) { - this.inputPaths = new ArrayList<>(); - } - - this.inputPaths.addAll(inputPaths); - } protected List relativizeRootPaths; @@ -84,6 +81,14 @@ public abstract class AbstractAnalysisPmdSubcommand { +abstract class BaseCommandTest> { protected abstract T createCommand(); @@ -30,6 +30,7 @@ abstract class BaseCommandTest { protected T setupAndParse(final String... params) { final T cmd = createCommand(); final ParseResult parseResult = parseCommand(cmd, params); + cmd.validate(); assertThat(parseResult.errors(), Matchers.empty()); From 4aedeec734fc194f877f4e8936b970d2b32a54d1 Mon Sep 17 00:00:00 2001 From: Debamoy Datta Date: Sat, 7 Oct 2023 17:11:16 +0530 Subject: [PATCH 13/61] #1831 resolved the issue --- .../pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java index d7cd0ce1e5..2aa20201fa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; import net.sourceforge.pmd.lang.ast.NodeStream; + import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.JModifier; @@ -24,7 +25,7 @@ public class DetachedTestCaseRule extends AbstractJavaRulechainRule { // looks like a test case methods.filter(m -> m.getArity() == 0 && m.isVoid() - && !m.getModifiers().hasAny(JModifier.STATIC, JModifier.PRIVATE, JModifier.PROTECTED)) + && !m.getModifiers().hasAny(JModifier.STATIC, JModifier.PRIVATE, JModifier.PROTECTED, JModifier.ABSTRACT)) // the method itself has no annotation .filter(it -> it.getDeclaredAnnotations().isEmpty()) .forEach(m -> addViolation(data, m)); From fc9767b65bf7241c49b2a8d87f07b98d59a7e68e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Oct 2023 15:05:49 +0200 Subject: [PATCH 14/61] [core] XSLTRenderer: Close original writer at the end Fixes #4717 --- docs/pages/release_notes.md | 3 +++ .../java/net/sourceforge/pmd/renderers/AbstractRenderer.java | 1 + .../main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java | 3 +++ 3 files changed, 7 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a892d43832..9ce81f8895 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -49,6 +49,8 @@ The remaining section describes the complete release notes for 7.0.0. #### Fixed issues +* core + * [#4717](https://github.com/pmd/pmd/issues/4717): \[core] XSLTRenderer doesn't close report file * java-codestyle * [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present @@ -439,6 +441,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4454](https://github.com/pmd/pmd/issues/4454): \[core] "Unknown option: '-min'" but is referenced in documentation * [#4611](https://github.com/pmd/pmd/pull/4611): \[core] Fix loading language properties from env vars * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first + * [#4717](https://github.com/pmd/pmd/issues/4717): \[core] XSLTRenderer doesn't close report file * cli * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java index 6eaecd5d37..d633d4dead 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java @@ -96,6 +96,7 @@ public abstract class AbstractRenderer extends AbstractPropertySource implements } @Override + // TODO: consider to rename the flush method - this is actually closing the writer public void flush() { if (writer == null) { // might happen, if no writer is set. E.g. in maven-pmd-plugin's PmdCollectingRenderer diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java index 7bb613d310..de3cc8ef65 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java @@ -28,6 +28,7 @@ import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import net.sourceforge.pmd.internal.util.IOUtil; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; @@ -129,6 +130,8 @@ public class XSLTRenderer extends XMLRenderer { transformer.transform(source, result); } catch (TransformerException e) { throw new RuntimeException(e); + } finally { + IOUtil.closeQuietly(outputWriter); } } From 95b1150e258740697db7101bebb9fb240b9f8be1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Oct 2023 15:06:15 +0200 Subject: [PATCH 15/61] Add @nakul777 as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 113 +++++++++++++------------- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e6cdc3259b..16db6c8aba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7268,6 +7268,15 @@ "contributions": [ "bug" ] + }, + { + "login": "nakul777", + "name": "Nakul Sharma", + "avatar_url": "https://avatars.githubusercontent.com/u/1551545?v=4", + "profile": "https://github.com/nakul777", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 64be0f432d..2c034396fb 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -527,510 +527,511 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Nahuel Barrios

🐛 +
Nakul Sharma

🐛
Nathan Braun

🐛
Nathan Reynolds

🐛
Nathan Reynolds

🐛
Nathanaël

🐛
Naveen

💻
Nazdravi

🐛 -
Neha-Dhonde

🐛 +
Neha-Dhonde

🐛
Nicholas Doyle

🐛
Nick Butcher

🐛
Nico Gallinal

🐛
Nicola Dal Maso

🐛
Nicolas Filotto

💻
Nicolas Vervelle

🐛 -
Nicolas Vuillamy

📖 +
Nicolas Vuillamy

📖
Nikita Chursin

🐛
Niklas Baudy

🐛
Nikolas Havrikov

🐛
Nilesh Virkar

🐛
Nimit Patel

🐛
Niranjan Harpale

🐛 -
Nirvik Patel

💻 +
Nirvik Patel

💻
Noah Sussman

🐛
Noah0120

🐛
Noam Tamim

🐛
Noel Grandin

🐛
Olaf Haalstra

🐛
Oleg Andreych

💻 🐛 -
Oleg Pavlenko

🐛 +
Oleg Pavlenko

🐛
Oleksii Dykov

💻 🐛
Oliver Eikemeier

🐛
Oliver Siegmar

💵
Olivier Parent

💻 🐛
Ollie Abbey

💻 🐛
OverDrone

🐛 -
Ozan Gulle

💻 🐛 +
Ozan Gulle

💻 🐛
PUNEET JAIN

🐛
Parbati Bose

🐛
Paul Berg

🐛
Paul Guyot

💻
Pavel Bludov

🐛
Pavel Mička

🐛 -
Pedro Nuno Santos

🐛 +
Pedro Nuno Santos

🐛
Pedro Rijo

🐛
Pelisse Romain

💻 📖 🐛
Per Abich

💻
Pete Davids

🐛
Peter Bruin

🐛
Peter Chittum

💻 🐛 -
Peter Cudmore

🐛 +
Peter Cudmore

🐛
Peter Kasson

🐛
Peter Kofler

🐛
Peter Paul Bakker

💻
Pham Hai Trung

🐛
Philip Graf

💻 🐛
Philip Hachey

🐛 -
Philippe Ozil

🐛 +
Philippe Ozil

🐛
Phinehas Artemix

🐛
Phokham Nonava

🐛
Pim van der Loos

💻 ⚠️
Piotr Szymański

🐛
Piotrek Żygieło

💻 🐛 📖
Pranay Jaiswal

🐛 -
Prasad Kamath

🐛 +
Prasad Kamath

🐛
Prasanna

🐛
Presh-AR

🐛
Puneet1726

🐛
Rafael Cortês

🐛
RaheemShaik999

🐛
RajeshR

💻 🐛 -
Ramachandra Mohan

🐛 +
Ramachandra Mohan

🐛
Ramel0921

🐛
Raquel Pau

🐛
Ravikiran Janardhana

🐛
Reda Benhemmouche

🐛
Renato Oliveira

💻 🐛
Rich DiCroce

🐛 -
Richard Corfield

💻 +
Richard Corfield

💻
Richard Corfield

🐛 💻
Riot R1cket

🐛
Rishabh Jain

🐛
RishabhDeep Singh

🐛
Robbie Martinus

💻 🐛
Robert Henry

🐛 -
Robert Mihaly

🐛 +
Robert Mihaly

🐛
Robert Painsi

🐛
Robert Russell

🐛
Robert Sösemann

💻 📖 📢 🐛
Robert Whitebit

🐛
Robin Richtsfeld

🐛
Robin Stocker

💻 🐛 -
Robin Wils

🐛 +
Robin Wils

🐛
RochusOest

🐛
Rodolfo Noviski

🐛
Rodrigo Casara

🐛
Rodrigo Fernandes

🐛
Roman Salvador

💻 🐛
Ronald Blaschke

🐛 -
Róbert Papp

🐛 +
Róbert Papp

🐛
Saikat Sengupta

🐛
Saksham Handu

🐛
Saladoc

🐛
Salesforce Bob Lightning

🐛
Sam Carlberg

🐛
Satoshi Kubo

🐛 -
Scott Kennedy

🐛 +
Scott Kennedy

🐛
Scott Wells

🐛 💻
Scrsloota

💻
Sebastian Bögl

🐛
Sebastian Schuberth

🐛
Sebastian Schwarz

🐛
Seren

🐛 💻 -
Sergey Gorbaty

🐛 +
Sergey Gorbaty

🐛
Sergey Kozlov

🐛
Sergey Yanzin

💻 🐛
Seth Wilcox

💻
Shubham

💻 🐛
Simon Abykov

💻 🐛
Simon Xiao

🐛 -
Srinivasan Venkatachalam

🐛 +
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛
Stanislav Myachenkov

💻
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛
Stefan Klöss-Schuster

🐛 -
Stefan Wolf

🐛 +
Stefan Wolf

🐛
Stephan H. Wissel

🐛
Stephen

🐛
Stephen Friedrich

🐛
Steve Babula

💻
Steven Stearns

🐛 💻
Stexxe

🐛 -
Stian Lågstad

🐛 +
Stian Lågstad

🐛
StuartClayton5

🐛
Supun Arunoda

🐛
Suren Abrahamyan

🐛
Suvashri

📖
SwatiBGupta1110

🐛
SyedThoufich

🐛 -
Szymon Sasin

🐛 +
Szymon Sasin

🐛
T-chuangxin

🐛
TERAI Atsuhiro

🐛
TIOBE Software

💻 🐛
Tarush Singh

💻
Taylor Smock

🐛
Techeira Damián

💻 🐛 -
Ted Husted

🐛 +
Ted Husted

🐛
TehBakker

🐛
The Gitter Badger

🐛
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛 -
Thomas Jones-Low

🐛 +
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛
ThrawnCA

🐛
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Copeland

🐛 💻 📖 -
Tom Daly

🐛 +
Tom Daly

🐛
Tomer Figenblat

🐛
Tomi De Lucca

💻 🐛
Torsten Kleiber

🐛
TrackerSB

🐛
Tyson Stewart

🐛
Ullrich Hafner

🐛 -
Utku Cuhadaroglu

💻 🐛 +
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛
Valeria

🐛
Valery Yatsynovich

📖
Vasily Anisimov

🐛
Vibhor Goyal

🐛
Vickenty Fesunov

🐛 -
Victor Noël

🐛 +
Victor Noël

🐛
Vincent Galloy

💻
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛
Vitaly

🐛 -
Vitaly Polonetsky

🐛 +
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛
Wayne J. Earl

🐛 -
Wchenghui

🐛 +
Wchenghui

🐛
Wener

💻
Will Winder

🐛
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛 -
XenoAmess

💻 🐛 +
XenoAmess

💻 🐛
Yang

💻
YaroslavTER

🐛
Yasar Shaikh

💻
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛 -
Yurii Dubinka

🐛 +
Yurii Dubinka

🐛
Zoltan Farkas

🐛
Zustin

🐛
aaronhurst-google

🐛 💻
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛 -
anicoara

🐛 +
anicoara

🐛
arunprasathav

🐛
asiercamara

🐛
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛 -
axelbarfod1

🐛 +
axelbarfod1

🐛
b-3-n

🐛
balbhadra9

🐛
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛 -
caesarkim

🐛 +
caesarkim

🐛
carolyujing

🐛
cbfiddle

🐛
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛 -
cosmoJFH

🐛 +
cosmoJFH

🐛
cristalp

🐛
crunsk

🐛
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛 📖
d1ss0nanz

🐛 -
dague1

📖 +
dague1

📖
dalizi007

💻
danbrycefairsailcom

🐛
dariansanity

🐛
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛 -
deepak-patra

🐛 +
deepak-patra

🐛
dependabot[bot]

💻 🐛
dinesh150

🐛
diziaq

🐛
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛 -
dylanleung

🐛 +
dylanleung

🐛
dzeigler

🐛
eant60

🐛
ekkirala

🐛
emersonmoura

🐛
eugenepugach

🐛
fairy

🐛 -
filiprafalowicz

💻 +
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛
freafrea

🐛
fsapatin

🐛
gracia19

🐛 -
guo fei

🐛 +
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛
henrik242

🐛
hongpuwu

🐛 -
hvbtup

💻 🐛 +
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛
jbennett2091

🐛
jcamerin

🐛 -
jkeener1

🐛 +
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛
karwer

🐛
kaulonline

🐛 -
kdaemonv

🐛 +
kdaemonv

🐛
kdebski85

🐛 💻
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛
koalalam

🐛
krzyk

🐛 -
lasselindqvist

🐛 +
lasselindqvist

🐛
lgemeinhardt

🐛
lihuaib

🐛
lonelyma1021

🐛
lpeddy

🐛
lujiefsi

💻
lukelukes

💻 -
lyriccoder

🐛 +
lyriccoder

🐛
marcelmore

🐛
matchbox

🐛
matthiaskraaz

🐛
meandonlyme

🐛
mikesive

🐛
milossesic

🐛 -
mluckam

💻 +
mluckam

💻
mohan-chinnappan-n

💻
mriddell95

🐛
mrlzh

🐛
msloan

🐛
mucharlaravalika

🐛
mvenneman

🐛 -
nareshl119

🐛 +
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛
nwcm

📖 🐛
oggboy

🐛
oinume

🐛 -
orimarko

💻 🐛 +
orimarko

💻 🐛
pacvz

💻
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛
pbrajesh1

🐛 -
phoenix384

🐛 +
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛
r-r-a-j

🐛 -
raghujayjunk

🐛 +
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛
rillig-tk

🐛 -
rmohan20

💻 🐛 +
rmohan20

💻 🐛
rnveach

🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛
sebbASF

🐛 -
sergeygorbaty

💻 +
sergeygorbaty

💻
shilko2013

🐛
shiomiyan

📖
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻 -
sratz

🐛 +
sratz

🐛
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛 -
test-git-hook

🐛 +
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛 💻
trentchilders

🐛 -
triandicAnt

🐛 +
triandicAnt

🐛
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛 -
xingsong

🐛 +
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛 -
zenglian

🐛 +
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛
Árpád Magosányi

🐛 -
任贵杰

🐛 +
任贵杰

🐛
茅延安

💻 From fbf2f77871575a4ec71bf102be1d7e7fb74d37bc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Oct 2023 16:07:17 +0200 Subject: [PATCH 16/61] [java] Don't cache jar files when loading classes This makes sure, that the underlying JarFiles are closed as soon as the streams to read single classes are closed. --- .../pmd/lang/java/symbols/internal/asm/Loader.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java index a44cc6bc03..d8d864875f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java @@ -8,6 +8,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -48,7 +49,11 @@ abstract class Loader { @Override @Nullable InputStream getInputStream() throws IOException { - return url.openStream(); + URLConnection connection = url.openConnection(); + // disable the cache, so that the underlying JarFile (if any) is closed, when + // the returned stream is closed - leaving no open files behind. + connection.setUseCaches(false); + return connection.getInputStream(); } @Override From e52fecc13051d20a24fec716ab31f467acc8e1cf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Oct 2023 16:07:49 +0200 Subject: [PATCH 17/61] [test] Close the streams in the tests --- .../sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt index 6e31b40285..46c3d9b272 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt @@ -188,7 +188,9 @@ abstract class BaseParsingHelper, T : RootNode val input = resourceLoader.getResourceAsStream(params.resourcePrefix + resourceName) ?: throw IllegalArgumentException("Unable to find resource file ${params.resourcePrefix + resourceName} from $resourceLoader") - return consume(input) + input.use { + return consume(input) + } } private fun consume(input: InputStream) = @@ -214,7 +216,9 @@ abstract class BaseParsingHelper, T : RootNode val input = (params.resourceLoader ?: javaClass).classLoader.getResourceAsStream(sourceFile) ?: throw IllegalArgumentException("Unable to find source file $sourceFile for $clazz") - return consume(input) + input.use { + return consume(input) + } } @JvmOverloads From 95ec080bf1873d45e06190d53bf9dff735b39a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 21 Oct 2023 02:07:56 -0300 Subject: [PATCH 18/61] Bump Groovy to 4.0.15 - We now support parsing all Groovy features from Groovy 3 and 4 - Support for 5 is not included as it would not work with Java 8 - Along the way, this also fixes #4674 --- pmd-groovy/pom.xml | 2 +- .../groovy/ast/impl/antlr4/GroovyToken.java | 93 +++++++ .../ast/impl/antlr4/GroovyTokenManager.java | 88 +++++++ .../pmd/lang/groovy/cpd/GroovyTokenizer.java | 49 +--- .../lang/groovy/cpd/GroovyTokenizerTest.java | 6 +- .../lang/groovy/cpd/testdata/cpdoff.groovy | 83 ++++++ .../pmd/lang/groovy/cpd/testdata/cpdoff.txt | 243 ++++++++++++++++++ .../pmd/lang/groovy/cpd/testdata/sample.txt | 174 +++++++++---- pom.xml | 4 +- 9 files changed, 647 insertions(+), 95 deletions(-) create mode 100644 pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java create mode 100644 pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyTokenManager.java create mode 100644 pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.groovy create mode 100644 pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.txt diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 1a5e3fbef9..cbf63c446e 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -31,7 +31,7 @@ pmd-core - org.codehaus.groovy + org.apache.groovy groovy diff --git a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java new file mode 100644 index 0000000000..535a9f97a2 --- /dev/null +++ b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java @@ -0,0 +1,93 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.groovy.ast.impl.antlr4; + +import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.lang.ast.GenericToken; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; +import net.sourceforge.pmd.lang.document.FileLocation; +import net.sourceforge.pmd.lang.document.TextDocument; +import net.sourceforge.pmd.lang.document.TextRegion; + +import groovyjarjarantlr4.v4.runtime.Lexer; +import groovyjarjarantlr4.v4.runtime.Token; + +/** + * A Groovy specific token representation. + * + * This is simply a copy of {@link AntlrToken} but + * referencing the jarjared version of antlr4 used by the groovy lexer. + */ +public class GroovyToken implements GenericToken { + + private final Token token; + private final GroovyToken previousComment; + private final TextDocument textDoc; + GroovyToken next; + + + /** + * Constructor + * + * @param token The antlr token implementation + * @param previousComment The previous comment + * @param textDoc The text document + */ + public GroovyToken(final Token token, final GroovyToken previousComment, TextDocument textDoc) { + this.token = token; + this.previousComment = previousComment; + this.textDoc = textDoc; + } + + @Override + public GroovyToken getNext() { + return next; + } + + @Override + public GroovyToken getPreviousComment() { + return previousComment; + } + + @Override + public CharSequence getImageCs() { + return token.getText(); + } + + /** Returns a text region with the coordinates of this token. */ + @Override + public TextRegion getRegion() { + return TextRegion.fromBothOffsets(token.getStartIndex(), token.getStopIndex() + 1); + } + + @Override + public FileLocation getReportLocation() { + return textDoc.toLocation(getRegion()); + } + + @Override + public boolean isEof() { + return getKind() == Token.EOF; + } + + @Override + public int compareTo(GroovyToken o) { + return getRegion().compareTo(o.getRegion()); + } + + @Override + @Experimental + public int getKind() { + return token.getType(); + } + + public boolean isHidden() { + return !isDefault(); + } + + public boolean isDefault() { + return token.getChannel() == Lexer.DEFAULT_TOKEN_CHANNEL; + } +} diff --git a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyTokenManager.java b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyTokenManager.java new file mode 100644 index 0000000000..313f386a80 --- /dev/null +++ b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyTokenManager.java @@ -0,0 +1,88 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.groovy.ast.impl.antlr4; + +import org.apache.groovy.parser.antlr4.GroovyLexer; + +import net.sourceforge.pmd.lang.TokenManager; +import net.sourceforge.pmd.lang.ast.TokenMgrError; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; +import net.sourceforge.pmd.lang.document.TextDocument; + +import groovyjarjarantlr4.v4.runtime.ANTLRErrorListener; +import groovyjarjarantlr4.v4.runtime.Lexer; +import groovyjarjarantlr4.v4.runtime.RecognitionException; +import groovyjarjarantlr4.v4.runtime.Recognizer; + +/** + * A Groovy specific token manager. + * + * This is simply a copy of {@link AntlrTokenManager} but + * referencing the jarjared version of antlr4 used by the groovy lexer. + */ +public class GroovyTokenManager implements TokenManager { + + private final Lexer lexer; + private final TextDocument textDoc; + private GroovyToken previousToken; + + + public GroovyTokenManager(final Lexer lexer, final TextDocument textDocument) { + this.lexer = lexer; + this.textDoc = textDocument; + resetListeners(); + } + + @Override + public GroovyToken getNextToken() { + GroovyToken nextToken = getNextTokenFromAnyChannel(); + while (!nextToken.isDefault()) { + nextToken = getNextTokenFromAnyChannel(); + } + return nextToken; + } + + private GroovyToken getNextTokenFromAnyChannel() { + /* + * Groovy's grammar doesn't hide away comments in a separate channel, + * but includes them as NL tokens with a different image + * See: https://github.com/apache/groovy/blob/GROOVY_4_0_15/src/antlr/GroovyLexer.g4#L980-L988 + */ + final GroovyToken previousComment; + if (previousToken != null && previousToken.getKind() == GroovyLexer.NL + && !"\n".equals(previousToken.getImage())) { + previousComment = previousToken; + } else { + previousComment = null; + } + + final GroovyToken currentToken = new GroovyToken(lexer.nextToken(), previousComment, textDoc); + if (previousToken != null) { + previousToken.next = currentToken; + } + previousToken = currentToken; + + return currentToken; + } + + private void resetListeners() { + lexer.removeErrorListeners(); + lexer.addErrorListener(new ErrorHandler()); + } + + private final class ErrorHandler implements ANTLRErrorListener { + + @Override + public void syntaxError(final Recognizer recognizer, + final Object offendingSymbol, + final int line, + final int charPositionInLine, + final String msg, + final RecognitionException ex) { + throw new TokenMgrError(line, charPositionInLine, textDoc.getFileId(), msg, ex); + } + } + +} diff --git a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizer.java b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizer.java index c7dacd2a7a..b180108fed 100644 --- a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizer.java +++ b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizer.java @@ -4,50 +4,27 @@ package net.sourceforge.pmd.lang.groovy.cpd; -import org.codehaus.groovy.antlr.SourceInfo; -import org.codehaus.groovy.antlr.parser.GroovyLexer; +import java.io.IOException; -import net.sourceforge.pmd.cpd.TokenFactory; -import net.sourceforge.pmd.cpd.Tokenizer; +import org.apache.groovy.parser.antlr4.GroovyLexer; + +import net.sourceforge.pmd.cpd.impl.TokenizerBase; +import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.document.TextDocument; +import net.sourceforge.pmd.lang.groovy.ast.impl.antlr4.GroovyToken; +import net.sourceforge.pmd.lang.groovy.ast.impl.antlr4.GroovyTokenManager; -import groovyjarjarantlr.Token; -import groovyjarjarantlr.TokenStream; -import groovyjarjarantlr.TokenStreamException; +import groovyjarjarantlr4.v4.runtime.CharStream; +import groovyjarjarantlr4.v4.runtime.CharStreams; /** * The Groovy Tokenizer */ -public class GroovyTokenizer implements Tokenizer { +public class GroovyTokenizer extends TokenizerBase { @Override - public void tokenize(TextDocument document, TokenFactory tokens) { - GroovyLexer lexer = new GroovyLexer(document.newReader()); - TokenStream tokenStream = lexer.plumb(); - - try { - Token token = tokenStream.nextToken(); - - while (token.getType() != Token.EOF_TYPE) { - String tokenText = token.getText(); - - - int lastCol; - int lastLine; - if (token instanceof SourceInfo) { - lastCol = ((SourceInfo) token).getColumnLast(); - lastLine = ((SourceInfo) token).getLineLast(); - } else { - // fallback - lastCol = token.getColumn() + tokenText.length(); - lastLine = token.getLine(); // todo inaccurate - } - - tokens.recordToken(tokenText, token.getLine(), token.getColumn(), lastLine, lastCol); - token = tokenStream.nextToken(); - } - } catch (TokenStreamException err) { - throw tokens.makeLexException(lexer.getLine(), lexer.getColumn(), err.getMessage(), err); - } + protected final TokenManager makeLexerImpl(TextDocument doc) throws IOException { + CharStream charStream = CharStreams.fromReader(doc.newReader(), doc.getFileId().getAbsolutePath()); + return new GroovyTokenManager(new GroovyLexer(charStream), doc); } } diff --git a/pmd-groovy/src/test/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizerTest.java b/pmd-groovy/src/test/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizerTest.java index eea8825a89..10570f4652 100644 --- a/pmd-groovy/src/test/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizerTest.java +++ b/pmd-groovy/src/test/java/net/sourceforge/pmd/lang/groovy/cpd/GroovyTokenizerTest.java @@ -14,9 +14,13 @@ class GroovyTokenizerTest extends CpdTextComparisonTest { super("groovy", ".groovy"); } - @Test void testSample() { doTest("sample"); } + + @Test + void testCpdOffAndOn() { + doTest("cpdoff"); + } } diff --git a/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.groovy b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.groovy new file mode 100644 index 0000000000..e14ddedeb1 --- /dev/null +++ b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.groovy @@ -0,0 +1,83 @@ +// Copied from https://github.com/zeebo404/btree +package net.sourceforge.pmd.cpd +/** + * User: Eric + * Date: 4/30/2015 + */ +class BTree extends BTreeNode { + + static def instance + + BlockManager manager + + BTree() { + instance = this + getLeaf(this) + manager = new BlockManager<>() + } + + // CPD-OFF + def split() { + + // create two new children + BTreeNode left = clone() + BTreeNode right = clone() + + // assign parent to this + [left, right]*.parent = this + + // Assign the left and right pointer lists + left.pointers = pointers.subList(0, count / 2 as int) as LinkedList + right.pointers = pointers.subList(count / 2 as int, count) as LinkedList + + // clear the rightmost left key + if (left.internalNode) { + left.pointers[-1].key = null + } + else { + left.rightSibling = right + right.leftSibling = left + } + + // reassign the parent node if not buckets + if (!bucketNode) { + [left, right].each { node -> node.pointers*.value*.parent = node } + } + + // add the children to this + pointers.clear() + addDirect(new BTreeEntry(right.smallestKey, left)) + addDirect(new BTreeEntry(null, right)) + + // Transform into a pointer node + if (leafNode) { + getPointer(this) + } + } + // CPD-ON + + def add(K key, V value) { + + if (count > 0 && search(key)) { + throw new IllegalArgumentException("$key is already in the tree") + } + + BlockManager.Block.BlockElement element = manager.element + element.value = value + + super.add key, element + } + + def delete(K key) { + + if (count > 0 && !search(key)) { + throw new IllegalArgumentException("$key is not in the tree") + } + + super.delete key + + if (count == 0) { + getLeaf(this) + } + } +} diff --git a/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.txt b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.txt new file mode 100644 index 0000000000..05a18a2ca1 --- /dev/null +++ b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/cpdoff.txt @@ -0,0 +1,243 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [// Copied from https://github.com/[ 1 49 + [\n] 49 50 +L2 + [package] 1 8 + [net] 9 12 + [.] 12 13 + [sourceforge] 13 24 + [.] 24 25 + [pmd] 25 28 + [.] 28 29 + [cpd] 29 32 + [\n] 32 33 +L3 + [/**\n * User: Eric\n * Date: 4/30/[ 1 4 +L6 + [\n] 4 5 +L7 + [class] 1 6 + [BTree] 7 12 + [<] 12 13 + [K] 13 14 + [,] 14 15 + [V] 16 17 + [>] 17 18 + [extends] 19 26 + [BTreeNode] 27 36 + [<] 36 37 + [K] 37 38 + [>] 38 39 + [{] 40 41 + [\n] 41 42 +L8 + [\n] 1 2 +L9 + [static] 2 8 + [def] 9 12 + [instance] 13 21 + [\n] 21 22 +L10 + [\n] 1 2 +L11 + [BlockManager] 2 14 + [<] 14 15 + [V] 15 16 + [>] 16 17 + [manager] 18 25 + [\n] 25 26 +L12 + [\n] 1 2 +L13 + [BTree] 2 7 + [(] 7 8 + [)] 8 9 + [{] 10 11 + [\n] 11 12 +L14 + [instance] 3 11 + [=] 12 13 + [this] 14 18 + [\n] 18 19 +L15 + [getLeaf] 3 10 + [(] 10 11 + [this] 11 15 + [)] 15 16 + [\n] 16 17 +L16 + [manager] 3 10 + [=] 11 12 + [new] 13 16 + [BlockManager] 17 29 + [<] 29 30 + [>] 30 31 + [(] 31 32 + [)] 32 33 + [\n] 33 34 +L17 + [}] 2 3 + [\n] 3 4 +L18 + [\n] 1 2 +L19 + [// CPD-OFF] 2 12 +L57 + [\n] 11 12 +L58 + [\n] 1 2 +L59 + [def] 2 5 + [add] 6 9 + [(] 9 10 + [K] 10 11 + [key] 12 15 + [,] 15 16 + [V] 17 18 + [value] 19 24 + [)] 24 25 + [{] 26 27 + [\n] 27 28 +L60 + [\n] 1 2 +L61 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [>] 13 14 + [0] 15 16 + [&&] 17 19 + [search] 20 26 + [(] 26 27 + [key] 27 30 + [)] 30 31 + [)] 31 32 + [{] 33 34 + [\n] 34 35 +L62 + [throw] 4 9 + [new] 10 13 + [IllegalArgumentException] 14 38 + [(] 38 39 + ["$] 39 41 + [key] 41 44 + [is already in the tree"] 45 68 + [)] 68 69 + [\n] 69 70 +L63 + [}] 3 4 + [\n] 4 5 +L64 + [\n] 1 2 +L65 + [BlockManager] 3 15 + [.] 15 16 + [Block] 16 21 + [.] 21 22 + [BlockElement] 22 34 + [<] 34 35 + [V] 35 36 + [>] 36 37 + [element] 38 45 + [=] 46 47 + [manager] 48 55 + [.] 55 56 + [element] 56 63 + [\n] 63 64 +L66 + [element] 3 10 + [.] 10 11 + [value] 11 16 + [=] 17 18 + [value] 19 24 + [\n] 24 25 +L67 + [\n] 1 2 +L68 + [super] 3 8 + [.] 8 9 + [add] 9 12 + [key] 13 16 + [,] 16 17 + [element] 18 25 + [\n] 25 26 +L69 + [}] 2 3 + [\n] 3 4 +L70 + [\n] 1 2 +L71 + [def] 2 5 + [delete] 6 12 + [(] 12 13 + [K] 13 14 + [key] 15 18 + [)] 18 19 + [{] 20 21 + [\n] 21 22 +L72 + [\n] 1 2 +L73 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [>] 13 14 + [0] 15 16 + [&&] 17 19 + [!] 20 21 + [search] 21 27 + [(] 27 28 + [key] 28 31 + [)] 31 32 + [)] 32 33 + [{] 34 35 + [\n] 35 36 +L74 + [throw] 4 9 + [new] 10 13 + [IllegalArgumentException] 14 38 + [(] 38 39 + ["$] 39 41 + [key] 41 44 + [is not in the tree"] 45 64 + [)] 64 65 + [\n] 65 66 +L75 + [}] 3 4 + [\n] 4 5 +L76 + [\n] 1 2 +L77 + [super] 3 8 + [.] 8 9 + [delete] 9 15 + [key] 16 19 + [\n] 19 20 +L78 + [\n] 1 2 +L79 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [==] 13 15 + [0] 16 17 + [)] 17 18 + [{] 19 20 + [\n] 20 21 +L80 + [getLeaf] 4 11 + [(] 11 12 + [this] 12 16 + [)] 16 17 + [\n] 17 18 +L81 + [}] 3 4 + [\n] 4 5 +L82 + [}] 2 3 + [\n] 3 4 +L83 + [}] 1 2 + [\n] 2 3 +EOF diff --git a/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt index 997a1005bd..2bc2b66f3d 100644 --- a/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt +++ b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt @@ -1,6 +1,7 @@ [Image] or [Truncated image[ Bcol Ecol L1 - [] 49 1 + [// Copied from https://github.com/[ 1 49 + [\n] 49 50 L2 [package] 1 8 [net] 9 12 @@ -10,7 +11,11 @@ L2 [pmd] 25 28 [.] 28 29 [cpd] 29 32 - [] 32 1 + [\n] 32 33 +L3 + [/**\n * User: Eric\n * Date: 4/30/[ 1 4 +L6 + [\n] 4 5 L7 [class] 1 6 [BTree] 7 12 @@ -25,36 +30,42 @@ L7 [K] 37 38 [>] 38 39 [{] 40 41 - [] 41 2 + [\n] 41 42 +L8 + [\n] 1 2 L9 [static] 2 8 [def] 9 12 [instance] 13 21 - [] 21 2 + [\n] 21 22 +L10 + [\n] 1 2 L11 [BlockManager] 2 14 [<] 14 15 [V] 15 16 [>] 16 17 [manager] 18 25 - [] 25 2 + [\n] 25 26 +L12 + [\n] 1 2 L13 [BTree] 2 7 [(] 7 8 [)] 8 9 [{] 10 11 - [] 11 3 + [\n] 11 12 L14 [instance] 3 11 [=] 12 13 [this] 14 18 - [] 18 3 + [\n] 18 19 L15 [getLeaf] 3 10 [(] 10 11 [this] 11 15 [)] 15 16 - [] 16 3 + [\n] 16 17 L16 [manager] 3 10 [=] 11 12 @@ -64,17 +75,24 @@ L16 [>] 30 31 [(] 31 32 [)] 32 33 - [] 33 2 + [\n] 33 34 L17 [}] 2 3 - [] 3 2 + [\n] 3 4 +L18 + [\n] 1 2 L19 [def] 2 5 [split] 6 11 [(] 11 12 [)] 12 13 [{] 14 15 - [] 15 3 + [\n] 15 16 +L20 + [\n] 1 2 +L21 + [// create two new children] 3 29 + [\n] 29 30 L22 [BTreeNode] 3 12 [<] 12 13 @@ -85,7 +103,7 @@ L22 [clone] 23 28 [(] 28 29 [)] 29 30 - [] 30 3 + [\n] 30 31 L23 [BTreeNode] 3 12 [<] 12 13 @@ -96,7 +114,12 @@ L23 [clone] 24 29 [(] 29 30 [)] 30 31 - [] 31 3 + [\n] 31 32 +L24 + [\n] 1 2 +L25 + [// assign parent to this] 3 27 + [\n] 27 28 L26 [\[] 3 4 [left] 4 8 @@ -107,7 +130,12 @@ L26 [parent] 18 24 [=] 25 26 [this] 27 31 - [] 31 3 + [\n] 31 32 +L27 + [\n] 1 2 +L28 + [// Assign the left and right point[ 3 45 + [\n] 45 46 L29 [left] 3 7 [.] 7 8 @@ -127,7 +155,7 @@ L29 [)] 55 56 [as] 57 59 [LinkedList] 60 70 - [] 70 3 + [\n] 70 71 L30 [right] 3 8 [.] 8 9 @@ -147,7 +175,12 @@ L30 [)] 60 61 [as] 62 64 [LinkedList] 65 75 - [] 75 3 + [\n] 75 76 +L31 + [\n] 1 2 +L32 + [// clear the rightmost left key] 3 34 + [\n] 34 35 L33 [if] 3 5 [(] 6 7 @@ -156,7 +189,7 @@ L33 [internalNode] 12 24 [)] 24 25 [{] 26 27 - [] 27 4 + [\n] 27 28 L34 [left] 4 8 [.] 8 9 @@ -169,31 +202,36 @@ L34 [key] 22 25 [=] 26 27 [null] 28 32 - [] 32 3 + [\n] 32 33 L35 [}] 3 4 - [] 4 3 + [\n] 4 5 L36 [else] 3 7 [{] 8 9 - [] 9 4 + [\n] 9 10 L37 [left] 4 8 [.] 8 9 [rightSibling] 9 21 [=] 22 23 [right] 24 29 - [] 29 4 + [\n] 29 30 L38 [right] 4 9 [.] 9 10 [leftSibling] 10 21 [=] 22 23 [left] 24 28 - [] 28 3 + [\n] 28 29 L39 [}] 3 4 - [] 4 3 + [\n] 4 5 +L40 + [\n] 1 2 +L41 + [// reassign the parent node if not[ 3 45 + [\n] 45 46 L42 [if] 3 5 [(] 6 7 @@ -201,7 +239,7 @@ L42 [bucketNode] 8 18 [)] 18 19 [{] 20 21 - [] 21 4 + [\n] 21 22 L43 [\[] 4 5 [left] 5 9 @@ -223,17 +261,22 @@ L43 [=] 62 63 [node] 64 68 [}] 69 70 - [] 70 3 + [\n] 70 71 L44 [}] 3 4 - [] 4 3 + [\n] 4 5 +L45 + [\n] 1 2 +L46 + [// add the children to this] 3 30 + [\n] 30 31 L47 [pointers] 3 11 [.] 11 12 [clear] 12 17 [(] 17 18 [)] 18 19 - [] 19 3 + [\n] 19 20 L48 [addDirect] 3 12 [(] 12 13 @@ -247,7 +290,7 @@ L48 [left] 47 51 [)] 51 52 [)] 52 53 - [] 53 3 + [\n] 53 54 L49 [addDirect] 3 12 [(] 12 13 @@ -259,26 +302,33 @@ L49 [right] 34 39 [)] 39 40 [)] 40 41 - [] 41 3 + [\n] 41 42 +L50 + [\n] 1 2 +L51 + [// Transform into a pointer node] 3 35 + [\n] 35 36 L52 [if] 3 5 [(] 6 7 [leafNode] 7 15 [)] 15 16 [{] 17 18 - [] 18 4 + [\n] 18 19 L53 [getPointer] 4 14 [(] 14 15 [this] 15 19 [)] 19 20 - [] 20 3 + [\n] 20 21 L54 [}] 3 4 - [] 4 2 + [\n] 4 5 L55 [}] 2 3 - [] 3 2 + [\n] 3 4 +L56 + [\n] 1 2 L57 [def] 2 5 [add] 6 9 @@ -290,7 +340,9 @@ L57 [value] 19 24 [)] 24 25 [{] 26 27 - [] 27 3 + [\n] 27 28 +L58 + [\n] 1 2 L59 [if] 3 5 [(] 6 7 @@ -304,20 +356,22 @@ L59 [)] 30 31 [)] 31 32 [{] 33 34 - [] 34 4 + [\n] 34 35 L60 [throw] 4 9 [new] 10 13 [IllegalArgumentException] 14 38 [(] 38 39 - [] 39 41 + ["$] 39 41 [key] 41 44 - [ is already in the tree] 44 68 + [is already in the tree"] 45 68 [)] 68 69 - [] 69 3 + [\n] 69 70 L61 [}] 3 4 - [] 4 3 + [\n] 4 5 +L62 + [\n] 1 2 L63 [BlockManager] 3 15 [.] 15 16 @@ -332,14 +386,16 @@ L63 [manager] 48 55 [.] 55 56 [element] 56 63 - [] 63 3 + [\n] 63 64 L64 [element] 3 10 [.] 10 11 [value] 11 16 [=] 17 18 [value] 19 24 - [] 24 3 + [\n] 24 25 +L65 + [\n] 1 2 L66 [super] 3 8 [.] 8 9 @@ -347,10 +403,12 @@ L66 [key] 13 16 [,] 16 17 [element] 18 25 - [] 25 2 + [\n] 25 26 L67 [}] 2 3 - [] 3 2 + [\n] 3 4 +L68 + [\n] 1 2 L69 [def] 2 5 [delete] 6 12 @@ -359,7 +417,9 @@ L69 [key] 15 18 [)] 18 19 [{] 20 21 - [] 21 3 + [\n] 21 22 +L70 + [\n] 1 2 L71 [if] 3 5 [(] 6 7 @@ -374,26 +434,30 @@ L71 [)] 31 32 [)] 32 33 [{] 34 35 - [] 35 4 + [\n] 35 36 L72 [throw] 4 9 [new] 10 13 [IllegalArgumentException] 14 38 [(] 38 39 - [] 39 41 + ["$] 39 41 [key] 41 44 - [ is not in the tree] 44 64 + [is not in the tree"] 45 64 [)] 64 65 - [] 65 3 + [\n] 65 66 L73 [}] 3 4 - [] 4 3 + [\n] 4 5 +L74 + [\n] 1 2 L75 [super] 3 8 [.] 8 9 [delete] 9 15 [key] 16 19 - [] 19 3 + [\n] 19 20 +L76 + [\n] 1 2 L77 [if] 3 5 [(] 6 7 @@ -402,20 +466,20 @@ L77 [0] 16 17 [)] 17 18 [{] 19 20 - [] 20 4 + [\n] 20 21 L78 [getLeaf] 4 11 [(] 11 12 [this] 12 16 [)] 16 17 - [] 17 3 + [\n] 17 18 L79 [}] 3 4 - [] 4 2 + [\n] 4 5 L80 [}] 2 3 - [] 3 1 + [\n] 3 4 L81 [}] 1 2 - [] 2 1 + [\n] 2 3 EOF diff --git a/pom.xml b/pom.xml index ef6b71625d..4ab80046e8 100644 --- a/pom.xml +++ b/pom.xml @@ -738,9 +738,9 @@ ${slf4j.version} - org.codehaus.groovy + org.apache.groovy groovy - 2.4.21 + 4.0.15 com.google.code.gson From 19a9a4bd3629aaebd866c10a680933e309bab967 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 10:16:44 +0200 Subject: [PATCH 19/61] Revert "Improve stats reporting" This reverts commit 5355594b5109ac946316b596a10cffd8dcfb11ed. --- .../internal/asm/AsmSymbolResolver.java | 21 ------------------- .../java/symbols/internal/asm/ClassStub.java | 4 ---- 2 files changed, 25 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java index 75dd21a858..b9204fe6b8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java @@ -126,34 +126,13 @@ public class AsmSymbolResolver implements SymbolResolver { public void close() throws Exception { closed = true; Exception e = null; - LOG.trace("Closing resolver with entries for {} stubs", knownStubs.size()); - int numParsed = 0; - int numClosed = 0; - int numFailed = 0; - int numFailedQueries = 0; for (ClassStub stub : knownStubs.values()) { Closeable closeable = stub.getCloseable(); if (closeable != null) { LOG.trace("Closing stream for {}", stub); e = IOUtil.closeAndAccumulate(closeable, e); - numClosed++; - } else if (stub == failed) { - // Note that failed queries may occur under normal circumstances. - // Eg package names may be queried just to figure - // out whether they're packages or classes. - numFailedQueries++; - } else if (!stub.isFailed()) { - numParsed++; - } else { - numFailed++; } } - LOG.trace("Of {} distinct queries to the classloader, {} queries failed, " - + "{} classes were found and parsed successfully, " - + "{} were found but failed parsing (!), " - + "{} were found but never parsed.", - knownStubs.size(), numFailedQueries, numParsed, numFailed, numClosed); - knownStubs.clear(); if (e != null) { throw e; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index 45f7a76b5e..f28964ea75 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -154,10 +154,6 @@ final class ClassStub implements JClassSymbol, AsmStub, AnnotationOwner { return this.parseLock.getCloseable(); } - boolean isFailed() { - return this.parseLock.isFailed(); - } - @Override public AsmSymbolResolver getResolver() { return resolver; From a643c3ce29489c8c4525192d9820137cea9c5b11 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 10:16:51 +0200 Subject: [PATCH 20/61] Revert "Add close routines for class stubs" This reverts commit 644f85836b848c373f8c4dccdd7ebff9032f8e15. --- .../sourceforge/pmd/internal/util/IOUtil.java | 29 +++++---------- .../java/internal/JavaLanguageProcessor.java | 8 ----- .../pmd/lang/java/symbols/SymbolResolver.java | 36 ++----------------- .../internal/asm/AsmSymbolResolver.java | 28 --------------- .../java/symbols/internal/asm/ClassStub.java | 13 ------- .../java/symbols/internal/asm/Loader.java | 35 +++--------------- .../java/symbols/internal/asm/ParseLock.java | 10 ------ .../symbols/internal/ast/MapSymResolver.java | 6 ---- .../pmd/lang/java/types/TypeSystem.java | 12 +------ .../pmd/lang/java/JavaParsingHelper.java | 11 ++---- .../symbols/internal/asm/SigParserTest.kt | 9 ++--- .../lang/java/types/TestUtilitiesForTypes.kt | 8 ++--- 12 files changed, 25 insertions(+), 180 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java index d127d67c99..61e3ff1f91 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java @@ -161,7 +161,15 @@ public final class IOUtil { public static Exception closeAll(Collection closeables) { Exception composed = null; for (AutoCloseable it : closeables) { - composed = closeAndAccumulate(it, composed); + try { + it.close(); + } catch (Exception e) { + if (composed == null) { + composed = e; + } else { + composed.addSuppressed(e); + } + } } return composed; } @@ -187,31 +195,12 @@ public final class IOUtil { } - /** - * Close the given closeable. If it fails with an exception, - * either return that one or suppress it (if the parameter - * exception is already non-null). - */ - public static @Nullable Exception closeAndAccumulate(AutoCloseable closeable, @Nullable Exception pending) { - try { - closeable.close(); - } catch (Exception e) { - if (pending == null) { - return e; - } else { - pending.addSuppressed(e); - } - } - return pending; - } - // The following methods are taken from Apache Commons IO. // The dependency was removed from PMD 6 because it had a security issue, // and upgrading was not possible without upgrading to Java 8. // See https://github.com/pmd/pmd/pull/3968 // TODO PMD 7: consider bringing back commons-io and cleaning this class up. - public static void closeQuietly(Closeable closeable) { try { closeable.close(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java index 535d4f5f88..c3729bae3c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java @@ -121,15 +121,7 @@ public class JavaLanguageProcessor extends BatchLanguageProcessor stack = listOf(first, others); - @Override public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { for (SymbolResolver resolver : stack) { @@ -83,34 +81,6 @@ public interface SymbolResolver extends AutoCloseable { } return null; } - - - @Override - public void close() throws Exception { - Exception e = IOUtil.closeAll(listOf(first, others)); - if (e != null) { - throw e; - } - } - }; - } - - - /** - * Return a resolver that delegates to the given resolver without closing it. - */ - static SymbolResolver closeShieldResolver(SymbolResolver resolver) { - return new SymbolResolver() { - @Override - public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { - return resolver.resolveClassFromBinaryName(binaryName); - } - - - @Override - public void close() { - // don't close the underlying resolver - } }; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java index b9204fe6b8..8da87a9520 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmSymbolResolver.java @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.io.Closeable; import java.io.InputStream; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -13,10 +12,7 @@ import java.util.concurrent.ConcurrentMap; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.objectweb.asm.Opcodes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import net.sourceforge.pmd.internal.util.IOUtil; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; import net.sourceforge.pmd.lang.java.symbols.internal.asm.Loader.FailedLoader; @@ -29,8 +25,6 @@ import net.sourceforge.pmd.util.AssertionUtil; */ public class AsmSymbolResolver implements SymbolResolver { - private static final Logger LOG = LoggerFactory.getLogger(AsmSymbolResolver.class); - static final int ASM_API_V = Opcodes.ASM9; private final TypeSystem ts; @@ -44,7 +38,6 @@ public class AsmSymbolResolver implements SymbolResolver { * instead of caching failure cases separately. */ private final ClassStub failed; - private boolean closed = false; public AsmSymbolResolver(TypeSystem ts, Classpath classLoader) { this.ts = ts; @@ -56,9 +49,6 @@ public class AsmSymbolResolver implements SymbolResolver { @Override public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) { AssertionUtil.requireParamNotNull("binaryName", binaryName); - if (closed) { - throw new IllegalStateException("Resolver closed: " + binaryName); - } String internalName = getInternalName(binaryName); @@ -120,22 +110,4 @@ public class AsmSymbolResolver implements SymbolResolver { return new ClassStub(this, iname, loader, observedArity); }); } - - - @Override - public void close() throws Exception { - closed = true; - Exception e = null; - for (ClassStub stub : knownStubs.values()) { - Closeable closeable = stub.getCloseable(); - if (closeable != null) { - LOG.trace("Closing stream for {}", stub); - e = IOUtil.closeAndAccumulate(closeable, e); - } - } - knownStubs.clear(); - if (e != null) { - throw e; - } - } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index f28964ea75..fe31977e30 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -139,21 +138,9 @@ final class ClassStub implements JClassSymbol, AsmStub, AnnotationOwner { protected boolean postCondition() { return signature != null && enclosingInfo != null; } - - - @Override - public @Nullable Closeable getCloseable() { - return loader.getInputStream(); - } }; } - - /** Return the closeable, or null if no system resources need to be closed. */ - @Nullable Closeable getCloseable() { - return this.parseLock.getCloseable(); - } - @Override public AsmSymbolResolver getResolver() { return resolver; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java index 516e55bc1a..8289601568 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/Loader.java @@ -5,74 +5,49 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -abstract class Loader implements Closeable { +abstract class Loader { - /** - * Return an input stream that must be closed by the caller. - * This method can be called exactly once. Return null if - * the loader is failed, or if the stream has already been returned. - */ - abstract @Nullable InputStream getInputStream(); + @Nullable + abstract InputStream getInputStream() throws IOException; static class FailedLoader extends Loader { static final FailedLoader INSTANCE = new FailedLoader(); - @Override @Nullable InputStream getInputStream() { return null; } - @Override public String toString() { return "(failed loader)"; } - - @Override - public void close() throws IOException { - // do nothing - } } static class StreamLoader extends Loader { - private final @NonNull String name; - private InputStream stream; + private final @NonNull InputStream stream; StreamLoader(@NonNull String name, @NonNull InputStream stream) { this.name = name; this.stream = stream; } - @Override @NonNull InputStream getInputStream() { - InputStream result = stream; - this.stream = null; // null out to avoid double close - return result; + return stream; } - - @Override - public void close() throws IOException { - if (stream != null) { - stream.close(); - } - } - - @Override public String toString() { return "(StreamLoader for " + name + ")"; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index b4997f1cb8..ed8b234168 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -4,9 +4,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm; -import java.io.Closeable; - -import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,13 +71,6 @@ abstract class ParseLock { return true; } - - public @Nullable Closeable getCloseable() { - // do nothing by default - return null; - } - - @Override public String toString() { return "ParseLock{status=" + status + '}'; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java index 65a33acb41..3012ba9e17 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java @@ -35,10 +35,4 @@ final class MapSymResolver implements SymbolResolver { public @Nullable JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName) { return byCanonicalName.get(canonicalName); } - - - @Override - public void close() throws Exception { - // nothing to do - } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java index e1f54a069b..788dc9ec94 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java @@ -63,7 +63,7 @@ import net.sourceforge.pmd.util.CollectionUtil; * {@link JavaNode#getTypeSystem()}. */ @SuppressWarnings("PMD.CompareObjectsWithEquals") -public final class TypeSystem implements AutoCloseable { +public final class TypeSystem { /** * Top type of the reference type system. This is the type for the @@ -315,23 +315,13 @@ public final class TypeSystem implements AutoCloseable { return Objects.requireNonNull(sym, "sym"); } - private @NonNull JPrimitiveType createPrimitive(PrimitiveTypeKind kind, Class box) { return new JPrimitiveType(this, kind, new RealPrimitiveSymbol(this, kind), getBootStrapSymbol(box), HashTreePSet.empty()); } - /** - * This should only be called once all files have been processed. - */ - @Override - public void close() throws Exception { - this.resolver.close(); - } - // type creation routines - /** * Returns the class symbol for the given reflected class. This asks * the classloader of this type system. Returns null if the parameter diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java index 079aa21cf2..4a16d064d5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java @@ -29,9 +29,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.JavaParser; import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; import net.sourceforge.pmd.lang.java.internal.JavaLanguageProcessor; -import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; -import net.sourceforge.pmd.lang.java.symbols.internal.asm.AsmSymbolResolver; -import net.sourceforge.pmd.lang.java.symbols.internal.asm.Classpath; import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.internal.infer.TypeInferenceLogger; import net.sourceforge.pmd.lang.java.types.internal.infer.TypeInferenceLogger.SimpleLogger; @@ -48,11 +45,7 @@ public class JavaParsingHelper extends BaseParsingHelper { - Classpath classpath = Classpath.forClassLoader(JavaParsingHelper.class.getClassLoader()); - AsmSymbolResolver symResolver = new AsmSymbolResolver(ts, classpath); - return SymbolResolver.closeShieldResolver(symResolver); - }); + public static final TypeSystem TEST_TYPE_SYSTEM = TypeSystem.usingClassLoaderClasspath(JavaParsingHelper.class.getClassLoader()); /** This runs all processing stages when parsing. */ public static final JavaParsingHelper DEFAULT = new JavaParsingHelper( @@ -75,7 +68,7 @@ public class JavaParsingHelper extends BaseParsingHelper JTypeMirror) { val ts = testTypeSystem - val parsed = ts.asmLoader!!.sigParser.parseFieldType(this, sig) + val parsed = ts.asmLoader.sigParser.parseFieldType(this, sig) parsed shouldBe TypeDslOf(ts).test() } private fun LexicalScope.shouldThrowWhenParsingType(sig: String, matcher: (InvalidTypeSignatureException)->Unit={}) { val ex = shouldThrow { val ts = testTypeSystem - ts.asmLoader!!.sigParser.parseFieldType(this, sig) + ts.asmLoader.sigParser.parseFieldType(this, sig) } matcher(ex) } @@ -69,7 +66,7 @@ private fun LexicalScope.shouldParseMethod( ) { val ts = testTypeSystem val mockStub = mock(ExecutableStub::class.java) - `when`(mockStub.sigParser()).thenReturn(ts.asmLoader!!.sigParser) + `when`(mockStub.sigParser()).thenReturn(ts.asmLoader.sigParser) `when`(mockStub.enclosingTypeParameterOwner).thenReturn(null) `when`(mockStub.typeSystem).thenReturn(ts) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt index 8b190878da..90482a9828 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt @@ -34,12 +34,8 @@ val javaParser: JavaParsingHelper = JavaParsingHelper.DEFAULT val testTypeSystem: TypeSystem get() = JavaParsingHelper.TEST_TYPE_SYSTEM -/** - * This is here bc the method is package private. - * The resolver is not necessarily an AsmSymbolResolver so that's why - * the return type is nullable. - */ -val TypeSystem.asmLoader: AsmSymbolResolver? get() = this.resolver as? AsmSymbolResolver +// bc the method is package private +val TypeSystem.asmLoader: AsmSymbolResolver get() = this.resolver as AsmSymbolResolver fun TypeSystem.lub(vararg us: JTypeMirror): JTypeMirror = lub(us.toList()) fun TypeSystem.glb(vararg us: JTypeMirror): JTypeMirror = glb(us.toList()) From 14ef905fab58e56b6526ed93c45869cf0bfe26aa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 10:19:13 +0200 Subject: [PATCH 21/61] Use Math.max MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Fournier --- .../net/sourceforge/pmd/internal/util/ClasspathClassLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index 7d9fe0a274..5ca4fd876e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -192,7 +192,7 @@ public class ClasspathClassLoader extends URLClassLoader { // always first search in jrt-fs, if available if (fileSystem != null) { int lastSlash = name.lastIndexOf('/'); - String packageName = name.substring(0, lastSlash != -1 ? lastSlash : 0); + String packageName = name.substring(0, Math.max(lastSlash, 0)); Set moduleNames = packagesDirsToModules.get(packageName); if (moduleNames != null) { LOG.trace("Trying to find {} in jrt-fs with packageName={} and modules={}", From d4725e6c1b7a28243d670b7cdc6cc0948dc36e22 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 15:14:45 +0200 Subject: [PATCH 22/61] [java] Improve logging of aux classpath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This includes some stats in AsmSymbolResolver. Co-authored-by: Clément Fournier --- .../pmd/cli/commands/internal/PmdCommand.java | 3 +- .../internal/util/ClasspathClassLoader.java | 14 +++++--- .../util/ClasspathClassLoaderTest.java | 28 ++++++++++------ .../java/internal/JavaLanguageProcessor.java | 11 +++++++ .../pmd/lang/java/symbols/SymbolResolver.java | 9 ++++++ .../internal/asm/AsmSymbolResolver.java | 32 +++++++++++++++++++ .../java/symbols/internal/asm/ClassStub.java | 8 +++++ .../java/symbols/internal/asm/ParseLock.java | 4 +++ .../symbols/internal/ast/MapSymResolver.java | 9 ++++++ .../pmd/lang/java/types/TypeSystem.java | 7 ++++ 10 files changed, 110 insertions(+), 15 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index ae2956238f..2da07e1adc 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -323,7 +323,8 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand return CliExitCode.ERROR; } - LOG.debug("Current classpath:\n{}", System.getProperty("java.class.path")); + LOG.debug("Runtime classpath:\n{}", System.getProperty("java.class.path")); + LOG.debug("Aux classpath: {}", configuration.getClassLoader()); if (showProgressBar) { if (reportFile == null) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index 5ca4fd876e..839887e2b4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -46,8 +46,9 @@ public class ClasspathClassLoader extends URLClassLoader { private static final Logger LOG = LoggerFactory.getLogger(ClasspathClassLoader.class); - private FileSystem fileSystem; String javaHome; + + private FileSystem fileSystem; private Map> packagesDirsToModules; static { @@ -71,7 +72,7 @@ public class ClasspathClassLoader extends URLClassLoader { private List fileToURL(List files) throws IOException { List urlList = new ArrayList<>(); for (File f : files) { - urlList.add(f.toURI().toURL()); + urlList.add(createURLFromPath(f.getAbsolutePath())); } return urlList; } @@ -137,7 +138,7 @@ public class ClasspathClassLoader extends URLClassLoader { */ private void initializeJrtFilesystem(Path filePath) { try { - LOG.debug("Detect Java Runtime Filesystem Provider in {}", filePath); + LOG.debug("Detected Java Runtime Filesystem Provider in {}", filePath); if (fileSystem != null) { throw new IllegalStateException("There is already a jrt filesystem. Do you have multiple jrt-fs.jar files on the classpath?"); @@ -152,7 +153,7 @@ public class ClasspathClassLoader extends URLClassLoader { // note: providing java.home here is crucial, so that the correct runtime image is loaded. // the class loader is only used to provide an implementation of JrtFileSystemProvider, if the current // Java runtime doesn't provide one (e.g. if running in Java 8). - this.javaHome = filePath.getParent().getParent().toString(); + javaHome = filePath.getParent().getParent().toString(); env.put("java.home", javaHome); LOG.debug("Creating jrt-fs with env {}", env); fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), env, loader); @@ -190,6 +191,8 @@ public class ClasspathClassLoader extends URLClassLoader { @Override public InputStream getResourceAsStream(String name) { // always first search in jrt-fs, if available + // note: we can't override just getResource(String) and return a jrt:/-URL, because the URL itself + // won't be connected to the correct JrtFileSystem and would just load using the system classloader. if (fileSystem != null) { int lastSlash = name.lastIndexOf('/'); String packageName = name.substring(0, Math.max(lastSlash, 0)); @@ -203,6 +206,9 @@ public class ClasspathClassLoader extends URLClassLoader { if (Files.exists(candidate)) { LOG.trace("Found {}", candidate); try { + // Note: The input streams from JrtFileSystem are ByteArrayInputStreams and do not + // need to be closed - we don't need to track these. The filesystem itself needs to be closed at the end. + // See https://github.com/openjdk/jdk/blob/970cd202049f592946f9c1004ea92dbd58abf6fb/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java#L334 return Files.newInputStream(candidate); } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java index 718d941ea2..50103b9091 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/internal/util/ClasspathClassLoaderTest.java @@ -22,6 +22,8 @@ import java.util.zip.ZipOutputStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class ClasspathClassLoaderTest { @TempDir @@ -42,7 +44,9 @@ class ClasspathClassLoaderTest { /** * This test case just documents the current behavior: Eventually we load * the class files from the system class loader, even if the auxclasspath - * is essentially empty. + * is essentially empty and no parent is provided. This is an unavoidable + * behavior of {@link java.lang.ClassLoader#getResource(java.lang.String)}, which will + * search the class loader built into the VM (BootLoader). */ @Test void loadEmptyClasspathNoParent() throws IOException { @@ -79,26 +83,30 @@ class ClasspathClassLoaderTest { /** * Verifies, that we load the class files from the runtime image of the correct java home. + * This tests multiple versions, in order to avoid that the test accidentally is successful when + * testing e.g. java17 and running the build with java17. In that case, we might load java.lang.Object + * from the system classloader and not from jrt-fs.jar. * *

- * This test only runs, if you have a folder ${HOME}/openjdk17. + * This test only runs, if you have a folder ${HOME}/openjdk{javaVersion}. *

*/ - @Test - void loadFromJava17() throws IOException { - Path java17Home = Paths.get(System.getProperty("user.home"), "openjdk17"); - assumeTrue(Files.isDirectory(java17Home), "Couldn't find java17 installation at " + java17Home); + @ParameterizedTest + @ValueSource(ints = {11, 17, 21}) + void loadFromJava(int javaVersion) throws IOException { + Path javaHome = Paths.get(System.getProperty("user.home"), "openjdk" + javaVersion); + assumeTrue(Files.isDirectory(javaHome), "Couldn't find java" + javaVersion + " installation at " + javaHome); - Path jrtfsPath = java17Home.resolve("lib/jrt-fs.jar"); - assertTrue(Files.isRegularFile(jrtfsPath), "java17 installation is incomplete. " + jrtfsPath + " not found!"); + Path jrtfsPath = javaHome.resolve("lib/jrt-fs.jar"); + assertTrue(Files.isRegularFile(jrtfsPath), "java" + javaVersion + " installation is incomplete. " + jrtfsPath + " not found!"); String classPath = jrtfsPath.toString(); try (ClasspathClassLoader loader = new ClasspathClassLoader(classPath, null)) { - assertEquals(java17Home.toString(), loader.javaHome); + assertEquals(javaHome.toString(), loader.javaHome); try (InputStream stream = loader.getResourceAsStream("java/lang/Object.class")) { assertNotNull(stream); try (DataInputStream data = new DataInputStream(stream)) { - assertClassFile(data, 17); + assertClassFile(data, javaVersion); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java index c3729bae3c..020fe79ed0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProcessor.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Objects; import org.checkerframework.checker.nullness.qual.NonNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.sourceforge.pmd.ViolationSuppressor; import net.sourceforge.pmd.lang.LanguageVersionHandler; @@ -36,6 +38,8 @@ import net.sourceforge.pmd.util.designerbindings.DesignerBindings; public class JavaLanguageProcessor extends BatchLanguageProcessor implements LanguageVersionHandler { + private static final Logger LOG = LoggerFactory.getLogger(JavaLanguageProcessor.class); + private final LanguageMetricsProvider myMetricsProvider = new JavaMetricsProvider(); private final JavaParser parser; private final JavaParser parserWithoutProcessing; @@ -52,6 +56,7 @@ public class JavaLanguageProcessor extends BatchLanguageProcessor diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index ed8b234168..7ed4f4d37f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -58,6 +58,10 @@ abstract class ParseLock { return getFinalStatus() == ParseStatus.FAILED; } + public boolean isNotParsed() { + return status == ParseStatus.NOT_PARSED; + } + // will be called in the critical section after parse is done protected void finishParse(boolean failed) { // by default do nothing diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java index 3012ba9e17..8d25309f3b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/MapSymResolver.java @@ -8,6 +8,8 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; @@ -16,6 +18,7 @@ import net.sourceforge.pmd.lang.java.symbols.SymbolResolver; * A symbol resolver that knows about a few hand-picked symbols. */ final class MapSymResolver implements SymbolResolver { + private static final Logger LOG = LoggerFactory.getLogger(MapSymResolver.class); private final Map byCanonicalName; private final Map byBinaryName; @@ -35,4 +38,10 @@ final class MapSymResolver implements SymbolResolver { public @Nullable JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName) { return byCanonicalName.get(canonicalName); } + + @Override + public void logStats() { + LOG.trace("Used {} classes by canonical name and {} classes by binary name", + byCanonicalName.size(), byBinaryName.size()); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java index 788dc9ec94..c256bfc690 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeSystem.java @@ -737,6 +737,13 @@ public final class TypeSystem { return new TypeVarImpl.RegularTypeVar(this, symbol, HashTreePSet.empty()); } + /** + * Called at the end of the analysis to log statistics about the loaded types. + */ + public void logStats() { + resolver.logStats(); + } + private static final class NullType implements JTypeMirror { private final TypeSystem ts; From bf55388e518cf4ac7c4d5438f25dfe58b66147d3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 15:50:15 +0200 Subject: [PATCH 23/61] [java] Explicitly closing the URLClassLoader of the JrtFileSystemProvider --- .../pmd/internal/util/ClasspathClassLoader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index 839887e2b4..2d5da86589 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -248,6 +248,14 @@ public class ClasspathClassLoader extends URLClassLoader { public void close() throws IOException { if (fileSystem != null) { fileSystem.close(); + // jrt created an own classloader to load the JrtFileSystemProvider class out of the + // jrt-fs.jar. This needs to be closed manually. + ClassLoader classLoader = fileSystem.getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + ((URLClassLoader) classLoader).close(); + } + packagesDirsToModules = null; + fileSystem = null; } super.close(); } From 11110049919af76a281a38e7426138aa26f19df6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Oct 2023 15:15:44 +0200 Subject: [PATCH 24/61] [cli] Disable closures in annotations feature of picocli This makes it probably a bit faster and doesn't leave an open groovy jar file behind. --- pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java index 4fb3877359..3e630bd9dc 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java @@ -13,6 +13,11 @@ public final class PmdCli { private PmdCli() { } public static void main(String[] args) { + // See https://github.com/remkop/picocli/blob/main/RELEASE-NOTES.md#-picocli-470 + // and https://picocli.info/#_closures_in_annotations + // we don't use this feature. Disabling it avoids leaving the groovy jar open + // caused by Class.forName("groovy.lang.Closure") + System.setProperty("picocli.disable.closures", "true"); final CommandLine cli = new CommandLine(new PmdRootCommand()) .setCaseInsensitiveEnumValuesAllowed(true); From 49bf4406341e65fdc0d031704aa22824de76d444 Mon Sep 17 00:00:00 2001 From: sandhu5 Date: Wed, 22 Nov 2023 23:01:06 -0600 Subject: [PATCH 25/61] Fix flaky SummaryHTMLRenderer --- .../net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java | 4 ++-- .../sourceforge/pmd/renderers/SummaryHTMLRendererTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java index 2632fc7297..20272afb30 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.renderers; import java.io.IOException; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -74,7 +74,7 @@ public class SummaryHTMLRenderer extends AbstractAccumulatingRenderer { } private static Map getSummary(Report report) { - Map summary = new HashMap<>(); + Map summary = new LinkedHashMap<>(); for (RuleViolation rv : report.getViolations()) { String name = rv.getRule().getName(); MutableInt count = summary.get(name); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java index 6b7260f577..89a60d00ff 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java @@ -69,8 +69,8 @@ class SummaryHTMLRendererTest extends AbstractRendererTest { return "PMD" + EOL + "

Summary

" + EOL + "" + EOL + "" + EOL - + "" + EOL - + "" + EOL + "
Rule nameNumber of violations
Boo1
Foo1
" + EOL + + "Foo1" + EOL + + "Boo1" + EOL + "" + EOL + "

Detail

" + EOL + "

PMD report

Problems found

" From 69e5307339a60b64481de8f2f85b4aa5c5b182b5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Nov 2023 19:12:59 +0100 Subject: [PATCH 26/61] Add @219sansim as a contributor --- .all-contributorsrc | 9 + docs/pages/pmd/projectdocs/credits.md | 227 +++++++++++++------------- 2 files changed, 123 insertions(+), 113 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5d8c873f7e..4232eb2de6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7296,6 +7296,15 @@ "contributions": [ "doc" ] + }, + { + "login": "219sansim", + "name": "219sansim", + "avatar_url": "https://avatars.githubusercontent.com/u/108684604?v=4", + "profile": "https://github.com/219sansim", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 63140f4a23..819a35f4de 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -16,1021 +16,1022 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From a8e80cc74b28174454a5b7a237278c4497bee12a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Nov 2023 19:15:45 +0100 Subject: [PATCH 27/61] [doc] Update release notes (#4750) --- docs/pages/release_notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 905f044caa..41e89d2ab9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -89,6 +89,7 @@ in the Migration Guide. * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" * core * [#1027](https://github.com/pmd/pmd/issues/1027): \[core] Apply the new PropertyDescriptor<Pattern> type where applicable + * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * doc * [#3175](https://github.com/pmd/pmd/issues/3175): \[doc] Document language module features * [#4659](https://github.com/pmd/pmd/pull/4659): \[doc] Improve ant documentation @@ -132,6 +133,7 @@ The following previously deprecated classes have been removed: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer - [219sansim](https://github.com/219sansim) (@219sansim) ### 🚀 Major Features and Enhancements @@ -524,6 +526,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4454](https://github.com/pmd/pmd/issues/4454): \[core] "Unknown option: '-min'" but is referenced in documentation * [#4611](https://github.com/pmd/pmd/pull/4611): \[core] Fix loading language properties from env vars * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first + * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * cli * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting @@ -788,6 +791,7 @@ Language specific fixes: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer - [219sansim](https://github.com/219sansim) (@219sansim) ### 📈 Stats * 5007 commits From 3fc9d8fc77e7bd5f2e5abcb94646e8dd32952354 Mon Sep 17 00:00:00 2001 From: Debamoy Datta Date: Sat, 25 Nov 2023 11:02:22 +0530 Subject: [PATCH 28/61] issue-1831 added test cases --- .../rule/errorprone/xml/DetachedTestCase.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml index 9d27d14d57..086d3848db 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml @@ -36,6 +36,22 @@ public class MyTest { ]]> + + Abstract methods should not be reported as detached test case + 0 + + + + missing annotation on public test case in JUnit 4 test class (regular annotation) 1 From de2a7e15ee139ca09bdc7801f43357547455d6c9 Mon Sep 17 00:00:00 2001 From: Andreas Bergander Date: Mon, 27 Nov 2023 15:35:06 +0100 Subject: [PATCH 29/61] Add allowCommentedBlocks property to EmptyControlStatementRule --- .../codestyle/EmptyControlStatementRule.java | 16 +++++++++++++- .../codestyle/xml/EmptyControlStatement.xml | 21 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java index 81faf170a8..00b626373b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java @@ -21,13 +21,25 @@ import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.rule.internal.JavaRuleUtil; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; public class EmptyControlStatementRule extends AbstractJavaRulechainRule { + private static final PropertyDescriptor ALLOW_COMMENTED_BLOCKS + = PropertyFactory.booleanProperty("allowCommentedBlocks") + .desc("Option for allowing empty but commented blocks. This is useful where a developer " + + "wants to have the code structure and explain why a condition does not require " + + "logic or to hold TODO comments for future work.") + .defaultValue(Boolean.FALSE) + .build(); + public EmptyControlStatementRule() { super(ASTFinallyClause.class, ASTSynchronizedStatement.class, ASTTryStatement.class, ASTDoStatement.class, ASTBlock.class, ASTForStatement.class, ASTForeachStatement.class, ASTWhileStatement.class, ASTIfStatement.class, ASTSwitchStatement.class, ASTInitializer.class); + + definePropertyDescriptor(ALLOW_COMMENTED_BLOCKS); } @Override @@ -145,7 +157,9 @@ public class EmptyControlStatementRule extends AbstractJavaRulechainRule { } private boolean isEmpty(JavaNode node) { - return node instanceof ASTBlock && node.getNumChildren() == 0 + boolean allowCommentedBlocks = getProperty(ALLOW_COMMENTED_BLOCKS); + + return (node instanceof ASTBlock && node.getNumChildren() == 0 && !(((ASTBlock) node).containsComment() && allowCommentedBlocks)) || node instanceof ASTEmptyStatement; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml index b0a5134918..528d6dd89f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml @@ -228,7 +228,7 @@ } ]]> - + empty initializer failure case (non static) 1 @@ -502,7 +502,8 @@ public class Foo { - empty if statement with comment + empty if statement with comment, disallow commented block + false 1 Empty if statement @@ -516,5 +517,21 @@ public class Foo { } } ]]> + + + + empty if statement with comment, allow commented block + true + 0 + + From b7b26f01f570f5c6cf5e8874ab9240d7cc417740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 28 Nov 2023 17:48:59 +0100 Subject: [PATCH 30/61] Fix #4753 --- .../pmd/lang/java/types/TypeConversion.java | 7 ++++ .../internal/infer/CaptureInferenceTest.kt | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java index e402a5d5da..e8927f0d1a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java @@ -144,6 +144,13 @@ public final class TypeConversion { * @return The capture conversion of t */ public static JTypeMirror capture(JTypeMirror t) { + if (t instanceof JTypeVar) { + // Need to capture the upper bound because that bound contributes the methods of the tvar. + // Eg in `>` the methods available in C may mention the type + // parameter of collection. But this is a wildcard `? super X` that needs to be captured. + JTypeVar tv = (JTypeVar) t; + return tv.withUpperBound(capture(tv.getUpperBound())); + } return t instanceof JClassType ? capture((JClassType) t) : t; } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt index d8c84cb49e..b4f84781af 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt @@ -458,6 +458,39 @@ class Foo { } } + parserTest("PMD crashes while using generics and wildcards #4753") { + + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ +import java.util.Collection; +import java.util.List; +import java.util.Arrays; +public class SubClass { + + public > C into(C collection) { + List list = null; + collection.addAll(list); + return collection; + } +} + """.trimIndent() + ) + + val cvar = acu.typeVar("C") + val tvar = acu.typeVar("T") + + spy.shouldBeOk { + val call = acu.firstMethodCall() + + call.methodType.shouldMatchMethod( + named = "addAll", + withFormals = listOf(java.util.Collection::class[`?` extends captureMatcher(`?` `super` tvar)]), + returning = boolean + ) + call.overloadSelectionInfo::isFailed shouldBe false + } + } + }) From c3a91ea495d24a04894f7c2a695a969b45745057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 28 Nov 2023 17:56:32 +0100 Subject: [PATCH 31/61] Update release notes --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 41e89d2ab9..5a833ada9a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -596,6 +596,7 @@ Language specific fixes: * [#4401](https://github.com/pmd/pmd/issues/4401): \[java] PMD 7 fails to build under Java 19 * [#4405](https://github.com/pmd/pmd/issues/4405): \[java] Processing error with ArrayIndexOutOfBoundsException * [#4583](https://github.com/pmd/pmd/issues/4583): \[java] Support JDK 21 (LTS) + * [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards * java-bestpractices * [#342](https://github.com/pmd/pmd/issues/342): \[java] AccessorMethodGeneration: Name clash with another public field not properly handled * [#755](https://github.com/pmd/pmd/issues/755): \[java] AccessorClassGeneration false positive for private constructors From d77d936daa6f971bc841fd317402cb9c5267c8c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 11:18:24 +0100 Subject: [PATCH 32/61] [doc] Update release notes (#4753) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5a833ada9a..b8fffd0c11 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -100,6 +100,8 @@ in the Migration Guide. * [#4741](https://github.com/pmd/pmd/pull/4741): Add pmd-compat6 module for maven-pmd-plugin * apex-performance * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop +* java + * [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards * java-codestyle * [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present From b69b1262926c17a142ebe407b1a937e15169c52f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 11:18:53 +0100 Subject: [PATCH 33/61] Add @soyodream as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 11 ++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4232eb2de6..da9496e72c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7305,6 +7305,15 @@ "contributions": [ "code" ] + }, + { + "login": "soyodream", + "name": "soyodream", + "avatar_url": "https://avatars.githubusercontent.com/u/151845313?v=4", + "profile": "https://github.com/soyodream", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 819a35f4de..cd5dc67b62 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -989,48 +989,49 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + From 1e8d5874ed5516bfe324aea226210efe66fe23aa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 14:27:15 +0100 Subject: [PATCH 34/61] [doc] Update release notes (#4754) --- docs/pages/release_notes.md | 11 +++++++++++ .../java/rule/codestyle/xml/EmptyControlStatement.xml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 905f044caa..abdb70a0bf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -82,6 +82,11 @@ in the Migration Guide. * {% rule java/codestyle/UseExplicitTypes %} reports usages of `var` keyword, which was introduced with Java 10. * {% rule xml/bestpractices/MissingEncoding %} finds XML files without explicit encoding. +**Changed Rules** + +* {% rule java/codestyle/EmptyControlStatement %}: The rule has a new property to allow empty blocks when + they contain a comment (`allowCommentedBlocks`). + #### Fixed issues * cli @@ -103,6 +108,7 @@ in the Migration Guide. * [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present * [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest + * [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property * java-errorprone * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string * javascript @@ -132,6 +138,7 @@ The following previously deprecated classes have been removed: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property - [Andreas Bergander](https://github.com/bergander) (@bergander) ### 🚀 Major Features and Enhancements @@ -390,6 +397,8 @@ can be parsed now. PMD should now be able to parse Apex code up to version 59.0 not necessary are allowed, if they separate expressions of different precedence. The other property `ignoreBalancing` (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions. +* {% rule java/codestyle/EmptyControlStatement %}: The rule has a new property to allow empty blocks when + they contain a comment (`allowCommentedBlocks`). **Java Design** @@ -664,6 +673,7 @@ Language specific fixes: * [#4557](https://github.com/pmd/pmd/issues/4557): \[java] UnnecessaryImport FP with static imports of overloaded methods * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present * [#4645](https://github.com/pmd/pmd/issues/4645): \[java] CommentDefaultAccessModifier - False Positive with JUnit5's ParameterizedTest + * [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property * java-design * [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression * [#1605](https://github.com/pmd/pmd/issues/1605): \[java] LawOfDemeter: False positive for standard UTF-8 charset name @@ -788,6 +798,7 @@ Language specific fixes: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property - [Andreas Bergander](https://github.com/bergander) (@bergander) ### 📈 Stats * 5007 commits diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml index 528d6dd89f..8d5dcdce10 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyControlStatement.xml @@ -520,7 +520,7 @@ public class Foo { - empty if statement with comment, allow commented block + empty if statement with comment, allow commented block (#4754) true 0 Date: Fri, 1 Dec 2023 14:27:42 +0100 Subject: [PATCH 35/61] Update @bergander as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5d8c873f7e..ed9c07953e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1667,7 +1667,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/8858497?v=4", "profile": "https://github.com/bergander", "contributions": [ - "bug" + "bug", + "code" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 63140f4a23..e838e605ed 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -811,7 +811,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + From 10c184b44bfa8a1564bd3cffac3cc4a6cb7b1b5c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 15:02:24 +0100 Subject: [PATCH 36/61] Fix checkstyle --- .../pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java index 2aa20201fa..9301e55a0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; import net.sourceforge.pmd.lang.ast.NodeStream; - import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.JModifier; From b0e2ab68c954cc879b329c6fb894ce266c91f8ef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 15:04:45 +0100 Subject: [PATCH 37/61] Add @Debamoy as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 181 +++++++++++++------------- 2 files changed, 100 insertions(+), 90 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e6cdc3259b..1caafabf51 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7268,6 +7268,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Debamoy", + "name": "Debamoy Datta", + "avatar_url": "https://avatars.githubusercontent.com/u/44639649?v=4", + "profile": "https://github.com/Debamoy", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 64be0f432d..eecdbcfbd8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -221,816 +221,817 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

0xflotus

💻 🐛

1henni

🐛

219sansim

💻

ALiNew

🐛

ASBrouwers

💻

Abhijit Sarkar

🐛

Abhishek Kumar

🐛

Adam

🐛

Adam

🐛

Adam Carroll

🐛

Adam Obuchowicz

🐛

Adrian Price

🐛

Adrien Lecharpentier

🐛

Aidan Harding

🐛

Akshat Bahety

💻 🐛

Akshay Thapa

🐛

Akshay Thapa

🐛

Alan Buttars

🐛

Alan Hohn

🐛

Alberto Fernández

💻 🐛

Alex

💻

Alex

🐛

Alex Rentz

🐛

Alex Saveau

🐛

Alex Saveau

🐛

Alex Shesterov

💻 🐛

Alexey Markevich

🐛

Alexey Naumov

🐛

Alexey Yudichev

🐛

Alix

🐛

Alix

🐛

Amish Shah

🐛

Amish Shah

🐛

Amit Prasad

🐛

Amitosh Swain Mahapatra

🐛

Anand Subramanian

💻 🐛

Anastasiia Koba

💻

Anatoly Trosinenko

💻 🐛

Andi Pabst

💻 🐛

Andrea

🐛

Andrea

🐛

Andrea Aime

🐛

Andreas Dangel

💻 📖 🐛 🚧

Andreas Deininger

📖

Andreas Markussen

🐛

Andreas Schmid

🐛

Andreas Turban

🐛

Andrei Paikin

🐛

Andrei Paikin

🐛

Andrew

🐛

Andrew Green

🐛

Andrey Bozhko

📖

Andrey Fomin

🐛

Andrey Hitrin

🐛

Andrey Mochalov

💻 🐛

Andro72

🐛

Andro72

🐛

Andrwyw

🐛

Andrés Catalán

🐛

Andy Pattenden

🐛

Andy Ray

🐛

Andy Robinson

🐛

Andy-2639

🐛

Ankush Somani

🐛

Ankush Somani

🐛

Anmol Kumar

🐛

Anthony Whitford

🐛

AnthonyKot

🐛

Aravind Hegde

🐛

Arda Aslan

🐛

Ari Fogel

🐛

Arnaud Jeansen

💻 🐛

Arnaud Jeansen

💻 🐛

Arpit Koolwal

🐛

Artem

💻 🐛

Artem

🐛

Artem Sheremet

🐛

Artur

🐛

Artur Bosch

🐛

Artur Dryomov

🐛

Artur Dryomov

🐛

Artur Ossowski

🐛

AshTheMash

🐛

Ashish Rana

🐛

Atul Kaushal

🐛

August Boland

🐛

Aurel Hudec

🐛

Austin

🐛

Austin

🐛

Austin Shalit

🐛

Austin Tice

🐛

Ayoub Kaanich

🐛

BBG

💻 📖 🐛

Bailey Tjiong

💻

Barthélemy L.

🐛

Basavaraj K N

🐛

Basavaraj K N

🐛

Basil Peace

🐛

Belle

🐛

Ben Lerner

🐛

Ben Manes

🐛

Ben McCann

🐛

Bendegúz Nagy

🐛

Bennet S Yee

🐛

Bennet S Yee

🐛

Benoit Lacelle

🐛

Bernardo Macêdo

🐛

Bernd Farka

🐛

Betina Cynthia Mamani

🐛

Bhanu Prakash Pamidi

💻 🐛

Bhargav Thanki

🐛

Binu R J

🐛

Binu R J

🐛

Björn Kautler

💻 🐛

Blightbuster

🐛

Bo Zhang

🐛

Bob "Wombat" Hogg

🐛

Bobby Wertman

🐛

Bolarinwa Saheed Olayemi

💻 🐛

Boris Petrov

🐛

Boris Petrov

🐛

Brad Kent

🐛

Brandon Mikeska

🐛

Brian Batronis

🐛

Brian Johnson

🐛

Brice Dutheil

💻 🐛

Bruno Ferreira

🐛

Bruno Harbulot

🐛

Bruno Harbulot

🐛

Bruno Ritz

🐛

Cameron Donaldson

🐛

Carlos Macasaet

🐛

Carsten Otto

🐛

Charlie Housh

🐛

Charlie Jonas

🐛

Chas Honton

🐛

Chas Honton

🐛

Chen Yang

🐛

Chotu

🐛

Chris Smith

🐛

Chris Toomey

🐛

Christian Hujer

🐛

Christian Pontesegger

🐛

ChristianWulf

🐛

ChristianWulf

🐛

Christofer Dutz

💻

Christoffer Anselm

🐛

Christophe Vidal

🐛

Christopher Dancy

🐛

Clemens Prill

🐛

Clint Chester

💻 🐛

Clément Fournier

💻 📖 🐛 🚧

Clément Fournier

💻 📖 🐛 🚧

Codacy Badger

🐛

Code-Nil

🐛

ColColonCleaner

🐛

Colin Ingarfield

🐛

Craig Andrews

🐛

Craig Muchinsky

🐛

Cyril

💻 🐛

Cyril

💻 🐛

Dale

💻

Damien Jiang

🐛

Dan Berindei

🐛

Dan Rollo

🐛

Dan Ziemba

🐛

Daniel Gredler

💻 🐛

Daniel Jipa

🐛

Daniel Jipa

🐛

Daniel Paul Searles

💻

Daniel Reigada

🐛

Danilo Pianini

🐛

Darko

🐛

David

🐛

David Atkinson

🐛

David Burström

💻 🐛

David Burström

💻 🐛

David Goaté

🐛

David Golpira

🐛

David Kovařík

🐛

David M. Karr (fullname at gmail.com)

🐛

David Renz

💻 🐛

David Renz

🐛

Dawid Ciok

🐛 💻

Dawid Ciok

🐛 💻

Deleted user

🐛

Dell Green

🐛

Dem Pilafian

🐛

Den

🐛

Denis Borovikov

💻 🐛

Dennie Reniers

💻 🐛

Dennis Kieselhorst

🐛

Dennis Kieselhorst

🐛

Derek P. Moore

🐛

Dichotomia

🐛

Dionisio Cortés Fernández

💻 🐛

Dmitri Bourlatchkov

🐛

Dmitriy Kuzmin

🐛

Dmytro Dashenkov

🐛

Drew Hall

🐛

Drew Hall

🐛

Dumitru Postoronca

🐛

Dylan Adams

🐛

Eden Hao

🐛

Edward Klimoshenko

🐛 💻

Egor Bredikhin

🐛

Elan P. Kugelmass

🐛

Elder S.

🐛

Elder S.

🐛

Eldrick Wega

📖

Emile

🐛

Eric

🐛

Eric Kintzer

🐛

Eric Perret

🐛

Eric Squires

🐛

Erich L Foster

🐛

Erich L Foster

🐛

Erik Bleske

🐛

Erik C. Thauvin

📖

Ernst Reissner

🐛

Ewan Tempero

🐛

F.W. Dekker

🐛

FSchliephacke

🐛

Facundo

🐛

Facundo

🐛

Federico Giust

🐛

Fedor Sherstobitov

🐛

Felix Lampe

🐛

Filip Golonka

🐛

Filipe Esperandio

💻 🐛

Filippo Nova

🐛

Francesco la Torre

🐛

Francesco la Torre

🐛

Francisco Duarte

🐛

Frieder Bluemle

🐛

Frits Jalvingh

💻 🐛

G. Bazior

🐛

Gabe Henkes

🐛

Gary Gregory

🐛

Genoud Magloire

🐛

Genoud Magloire

🐛

Geoffrey555

🐛

Georg Romstorfer

🐛

Gio

🐛

Gol

🐛

Gonzalo Exequiel Ibars Ingman

💻 🐛

GooDer

🐛

Gregor Riegler

🐛

Gregor Riegler

🐛

Grzegorz Olszewski

🐛

Gunther Schrijvers

💻 🐛

Gustavo Krieger

🐛

Guy Elsmore-Paddock

🐛

Görkem Mülayim

🐛

Hanzel Godinez

🐛

Haoliang Chen

🐛

Haoliang Chen

🐛

Harsh Kukreja

🐛

Hassan ALAMI

🐛

Heber

🐛

Henning Schmiedehausen

💻 🐛

Henning von Bargen

💻

Hervé Boutemy

🐛

Himanshu Pandey

🐛

Himanshu Pandey

🐛

Hokwang Lee

🐛

Hooperbloob

💻

Hung PHAN

🐛

IDoCodingStuffs

💻 🐛

Iccen Gan

🐛

Ignacio Mariano Tirabasso

🐛

Igor Melnichenko

🐛

Igor Melnichenko

🐛

Igor Moreno

🐛

Intelesis-MS

🐛

Iroha_

🐛

Ishan Srivastava

🐛

Ivano Guerini

🐛

Ivar Andreas Bonsaksen

🐛

Ivo Šmíd

🐛

Ivo Šmíd

🐛

JJengility

🐛

Jake Hemmerle

🐛

James Harrison

🐛 💻

Jan

🐛

Jan Aertgeerts

💻 🐛

Jan Brümmer

🐛

Jan Tříska

🐛

Jan Tříska

🐛

Jan-Lukas Else

🐛

Jason Qiu

💻 📖

Jason Williams

🐛

Jean-Paul Mayer

🐛

Jean-Simon Larochelle

🐛

Jeff Bartolotta

💻 🐛

Jeff Hube

💻 🐛

Jeff Hube

💻 🐛

Jeff Jensen

🐛

Jeff May

🐛

Jens Gerdes

🐛

Jeroen Borgers

🐛 💻 📢

Jeroen van Wilgenburg

📖

Jerome Russ

🐛

JerritEic

💻 📖 🐛

JerritEic

💻 📖 🐛

Jiri Pejchal

🐛

Jithin Sunny

🐛

Jiří Škorpil

🐛

Joao Machado

🐛

Jochen Krauss

🐛

Johan Hammar

🐛

John Karp

🐛

John Karp

🐛

John Zhang

🐛

John-Teng

💻 🐛

Jon Moroney

💻 🐛

Jonas Geiregat

🐛

Jonathan Wiesel

💻 🐛

Jordan

🐛

Jordi Llach

🐛

Jordi Llach

🐛

Jorge Solórzano

🐛

JorneVL

🐛

Jose Palafox

🐛

Jose Stovall

🐛

Joseph

💻

Joseph Heenan

🐛

Josh Feingold

💻 🐛

Josh Feingold

💻 🐛

Josh Holthaus

🐛

Joshua S Arquilevich

🐛

João Dinis Ferreira

📖

João Ferreira

💻 🐛

João Pedro Schmitt

🐛

Juan Martín Sotuyo Dodero

💻 📖 🐛 🚧

Juan Pablo Civile

🐛

Juan Pablo Civile

🐛

Julian Voronetsky

🐛

Julien

🐛

Julius

🐛

JustPRV

🐛

Jörn Huxhorn

🐛

KThompso

🐛

Kai Amundsen

🐛

Kai Amundsen

🐛

Karel Vervaeke

🐛

Karl-Andero Mere

🐛

Karl-Philipp Richter

🐛

Karsten Silz

🐛

Kazuma Watanabe

🐛

Kev

🐛

Keve Müller

🐛

Keve Müller

🐛

Kevin Guerra

💻

Kevin Jones

🐛 💻

Kevin Wayne

🐛

Kieran Black

🐛

Kirill Zubov

🐛

Kirk Clemens

💻 🐛

Klaus Hartl

🐛

Klaus Hartl

🐛

Koen Van Looveren

🐛

Kris Scheibe

💻 🐛

Krystian Dabrowski

🐛 💻

Kunal Thanki

🐛

LaLucid

💻

Larry Diamond

💻 🐛

Lars Knickrehm

🐛

Lars Knickrehm

🐛

Leo Gutierrez

🐛

LiGaOg

💻

Liam Sharp

🐛

Lintsi

🐛

Linus Fernandes

🐛

Lixon Lookose

🐛

Logesh

🐛

Logesh

🐛

Lorenzo Gabriele

🐛

Loïc Ledoyen

🐛

Lucas Silva

🐛

Lucas Soncini

💻 🐛

Luis Alcantar

💻

Lukasz Slonina

🐛

Lukebray

🐛

Lukebray

🐛

Lynn

💻 🐛

Lyor Goldstein

🐛

MCMicS

🐛

Macarse

🐛

Machine account for PMD

💻

Maciek Siemczyk

🐛

Maikel Steneker

💻 🐛

Maikel Steneker

💻 🐛

Maksim Moiseikin

🐛

Manfred Koch

🐛

Manuel Moya Ferrer

💻 🐛

Manuel Ryan

🐛

Marat Vyshegorodtsev

🐛

Marcel Härle

🐛

Marcello Fialho

🐛

Marcello Fialho

🐛

Marcin Rataj

🐛

Marcono1234

🐛

Mark Adamcin

🐛

Mark Hall

💻 🐛

Mark Kolich

🐛

Mark Pritchard

🐛

Markus Rathgeb

🐛

Markus Rathgeb

🐛

Marquis Wang

🐛

MartGit

🐛

Martin Feldsztejn

🐛

Martin Lehmann

🐛

Martin Spamer

🐛

Martin Tarjányi

🐛

MatFl

🐛

MatFl

🐛

Mateusz Stefanski

🐛

Mathieu Gouin

🐛

MatiasComercio

💻 🐛

Matt Benson

🐛

Matt De Poorter

🐛

Matt Hargett

💻 💵

Matt Harrah

🐛

Matt Harrah

🐛

Matt Nelson

🐛

Matthew Amos

🐛

Matthew Duggan

🐛

Matthew Hall

🐛

Matías Fraga

💻 🐛

Maxime Robert

💻 🐛

MetaBF

🐛

MetaBF

🐛

Michael

🐛

Michael Bell

🐛

Michael Bernstein

🐛

Michael Clay

🐛

Michael Dombrowski

🐛

Michael Hausegger

🐛

Michael Hoefer

🐛

Michael Hoefer

🐛

Michael Möbius

🐛

Michael N. Lipp

🐛

Michael Pellegrini

🐛

Michal Kordas

🐛

Michał Borek

🐛

Michał Kuliński

🐛

Miguel Núñez Díaz-Montes

🐛

Miguel Núñez Díaz-Montes

🐛

Mihai Ionut

🐛

Mirek Hankus

🐛

Mladjan Gadzic

🐛

MrAngry52

🐛

Muminur Choudhury

🐛

Mykhailo Palahuta

💻 🐛

Nagendra Kumar Singh

🐛

Nagendra Kumar Singh

🐛

Nahuel Barrios

🐛

Nathan Braun

🐛

Nathan Reynolds

🐛

Nathan Reynolds

🐛

Nathanaël

🐛

Naveen

💻

Nazdravi

🐛

Nazdravi

🐛

Neha-Dhonde

🐛

Nicholas Doyle

🐛

Nick Butcher

🐛

Nico Gallinal

🐛

Nicola Dal Maso

🐛

Nicolas Filotto

💻

Nicolas Vervelle

🐛

Nicolas Vervelle

🐛

Nicolas Vuillamy

📖

Nikita Chursin

🐛

Niklas Baudy

🐛

Nikolas Havrikov

🐛

Nilesh Virkar

🐛

Nimit Patel

🐛

Niranjan Harpale

🐛

Niranjan Harpale

🐛

Nirvik Patel

💻

Noah Sussman

🐛

Noah0120

🐛

Noam Tamim

🐛

Noel Grandin

🐛

Olaf Haalstra

🐛

Oleg Andreych

💻 🐛

Oleg Andreych

💻 🐛

Oleg Pavlenko

🐛

Oleksii Dykov

💻 🐛

Oliver Eikemeier

🐛

Oliver Siegmar

💵

Olivier Parent

💻 🐛

Ollie Abbey

💻 🐛

OverDrone

🐛

OverDrone

🐛

Ozan Gulle

💻 🐛

PUNEET JAIN

🐛

Parbati Bose

🐛

Paul Berg

🐛

Paul Guyot

💻

Pavel Bludov

🐛

Pavel Mička

🐛

Pavel Mička

🐛

Pedro Nuno Santos

🐛

Pedro Rijo

🐛

Pelisse Romain

💻 📖 🐛

Per Abich

💻

Pete Davids

🐛

Peter Bruin

🐛

Peter Chittum

💻 🐛

Peter Chittum

💻 🐛

Peter Cudmore

🐛

Peter Kasson

🐛

Peter Kofler

🐛

Peter Paul Bakker

💻

Pham Hai Trung

🐛

Philip Graf

💻 🐛

Philip Hachey

🐛

Philip Hachey

🐛

Philippe Ozil

🐛

Phinehas Artemix

🐛

Phokham Nonava

🐛

Pim van der Loos

💻 ⚠️

Piotr Szymański

🐛

Piotrek Żygieło

💻 🐛 📖

Pranay Jaiswal

🐛

Pranay Jaiswal

🐛

Prasad Kamath

🐛

Prasanna

🐛

Presh-AR

🐛

Puneet1726

🐛

Rafael Cortês

🐛

RaheemShaik999

🐛

RajeshR

💻 🐛

RajeshR

💻 🐛

Ramachandra Mohan

🐛

Ramel0921

🐛

Raquel Pau

🐛

Ravikiran Janardhana

🐛

Reda Benhemmouche

🐛

Renato Oliveira

💻 🐛

Rich DiCroce

🐛

Rich DiCroce

🐛

Richard Corfield

💻

Richard Corfield

🐛 💻

Riot R1cket

🐛

Rishabh Jain

🐛

RishabhDeep Singh

🐛

Robbie Martinus

💻 🐛

Robert Henry

🐛

Robert Henry

🐛

Robert Mihaly

🐛

Robert Painsi

🐛

Robert Russell

🐛

Robert Sösemann

💻 📖 📢 🐛

Robert Whitebit

🐛

Robin Richtsfeld

🐛

Robin Stocker

💻 🐛

Robin Stocker

💻 🐛

Robin Wils

🐛

RochusOest

🐛

Rodolfo Noviski

🐛

Rodrigo Casara

🐛

Rodrigo Fernandes

🐛

Roman Salvador

💻 🐛

Ronald Blaschke

🐛

Ronald Blaschke

🐛

Róbert Papp

🐛

Saikat Sengupta

🐛

Saksham Handu

🐛

Saladoc

🐛

Salesforce Bob Lightning

🐛

Sam Carlberg

🐛

Satoshi Kubo

🐛

Satoshi Kubo

🐛

Scott Kennedy

🐛

Scott Wells

🐛 💻

Scrsloota

💻

Sebastian Bögl

🐛

Sebastian Schuberth

🐛

Sebastian Schwarz

🐛

Seren

🐛 💻

Seren

🐛 💻

Sergey Gorbaty

🐛

Sergey Kozlov

🐛

Sergey Yanzin

💻 🐛

Seth Wilcox

💻

Shai Bennathan

🐛 💻

Shubham

💻 🐛

Simon Abykov

💻 🐛

Simon Abykov

💻 🐛

Simon Xiao

🐛

Srinivasan Venkatachalam

🐛

Stanislav Gromov

🐛

Stanislav Myachenkov

💻

Stefan Birkner

🐛

Stefan Bohn

🐛

Stefan Endrullis

🐛

Stefan Endrullis

🐛

Stefan Klöss-Schuster

🐛

Stefan Wolf

🐛

Stephan H. Wissel

🐛

Stephen

🐛

Stephen Friedrich

🐛

Steve Babula

💻

Steven Stearns

🐛 💻

Steven Stearns

🐛 💻

Stexxe

🐛

Stian Lågstad

🐛

StuartClayton5

🐛

Supun Arunoda

🐛

Suren Abrahamyan

🐛

Suvashri

📖

SwatiBGupta1110

🐛

SwatiBGupta1110

🐛

SyedThoufich

🐛

Szymon Sasin

🐛

T-chuangxin

🐛

TERAI Atsuhiro

🐛

TIOBE Software

💻 🐛

Tarush Singh

💻

Taylor Smock

🐛

Taylor Smock

🐛

Techeira Damián

💻 🐛

Ted Husted

🐛

TehBakker

🐛

The Gitter Badger

🐛

Theodoor

🐛

Thiago Henrique Hüpner

🐛

Thibault Meyer

🐛

Thibault Meyer

🐛

Thomas Güttler

🐛

Thomas Jones-Low

🐛

Thomas Smith

💻 🐛

ThrawnCA

🐛

Thunderforge

💻 🐛

Tim van der Lippe

🐛

Tobias Weimer

💻 🐛

Tobias Weimer

💻 🐛

Tom Copeland

🐛 💻 📖

Tom Daly

🐛

Tomer Figenblat

🐛

Tomi De Lucca

💻 🐛

Torsten Kleiber

🐛

TrackerSB

🐛

Tyson Stewart

🐛

Tyson Stewart

🐛

Ullrich Hafner

🐛

Utku Cuhadaroglu

💻 🐛

Valentin Brandl

🐛

Valeria

🐛

Valery Yatsynovich

📖

Vasily Anisimov

🐛

Vibhor Goyal

🐛

Vibhor Goyal

🐛

Vickenty Fesunov

🐛

Victor Noël

🐛

Vincent Galloy

💻

Vincent HUYNH

🐛

Vincent Maurin

🐛

Vincent Privat

🐛

Vishhwas

🐛

Vishhwas

🐛

Vitaly

🐛

Vitaly Polonetsky

🐛

Vojtech Polivka

🐛

Vsevolod Zholobov

🐛

Vyom Yadav

💻

Wang Shidong

🐛

Waqas Ahmed

🐛

Waqas Ahmed

🐛

Wayne J. Earl

🐛

Wchenghui

🐛

Wener

💻

Will Winder

🐛

William Brockhus

💻 🐛

Wilson Kurniawan

🐛

Wim Deblauwe

🐛

Wim Deblauwe

🐛

Woongsik Choi

🐛

XenoAmess

💻 🐛

Yang

💻

YaroslavTER

🐛

Yasar Shaikh

💻

Young Chan

💻 🐛

YuJin Kim

🐛

YuJin Kim

🐛

Yuri Dolzhenko

🐛

Yurii Dubinka

🐛

Zoltan Farkas

🐛

Zustin

🐛

aaronhurst-google

🐛 💻

alexmodis

🐛

andreoss

🐛

andreoss

🐛

andrey81inmd

💻 🐛

anicoara

🐛

arunprasathav

🐛

asiercamara

🐛

astillich-igniti

💻

avesolovksyy

🐛

avishvat

🐛

avishvat

🐛

avivmu

🐛

axelbarfod1

🐛

b-3-n

🐛

balbhadra9

🐛

base23de

🐛

bergander

🐛

berkam

💻 🐛

berkam

💻 🐛

breizh31

🐛

caesarkim

🐛

carolyujing

🐛

cbfiddle

🐛

cesares-basilico

🐛

chrite

🐛

ciufudean

📖

ciufudean

📖

cobratbq

🐛

coladict

🐛

cosmoJFH

🐛

cristalp

🐛

crunsk

🐛

cwholmes

🐛

cyberjj999

🐛

cyberjj999

🐛

cyw3

🐛 📖

d1ss0nanz

🐛

dague1

📖

dalizi007

💻

danbrycefairsailcom

🐛

dariansanity

🐛

darrenmiliband

🐛

darrenmiliband

🐛

davidburstrom

🐛

dbirkman-paloalto

🐛

deepak-patra

🐛

dependabot[bot]

💻 🐛

dinesh150

🐛

diziaq

🐛

dreaminpast123

🐛

dreaminpast123

🐛

duanyanan

🐛

dutt-sanjay

🐛

dylanleung

🐛

dzeigler

🐛

eant60

🐛

ekkirala

🐛

emersonmoura

🐛

emersonmoura

🐛

eugenepugach

🐛

fairy

🐛

filiprafalowicz

💻

foxmason

🐛

frankegabor

🐛

frankl

🐛

freafrea

🐛

freafrea

🐛

fsapatin

🐛

gracia19

🐛

guo fei

🐛

gurmsc5

🐛

gwilymatgearset

💻 🐛

haigsn

🐛

hemanshu070

🐛

hemanshu070

🐛

henrik242

🐛

hongpuwu

🐛

hvbtup

💻 🐛

igniti GmbH

🐛

ilovezfs

🐛

itaigilo

🐛

jakivey32

🐛

jakivey32

🐛

jbennett2091

🐛

jcamerin

🐛

jkeener1

🐛

jmetertea

🐛

johnra2

💻

josemanuelrolon

💻 🐛

kabroxiko

💻 🐛

kabroxiko

💻 🐛

karwer

🐛

kaulonline

🐛

kdaemonv

🐛

kdebski85

🐛 💻

kenji21

💻 🐛

kfranic

🐛

khalidkh

🐛

khalidkh

🐛

koalalam

🐛

krzyk

🐛

lasselindqvist

🐛

lgemeinhardt

🐛

lihuaib

🐛

lonelyma1021

🐛

lpeddy

🐛

lpeddy

🐛

lujiefsi

💻

lukelukes

💻

lyriccoder

🐛

marcelmore

🐛

matchbox

🐛

matthiaskraaz

🐛

meandonlyme

🐛

meandonlyme

🐛

mikesive

🐛

milossesic

🐛

mluckam

💻

mohan-chinnappan-n

💻

mriddell95

🐛

mrlzh

🐛

msloan

🐛

msloan

🐛

mucharlaravalika

🐛

mvenneman

🐛

nareshl119

🐛

nicolas-harraudeau-sonarsource

🐛

noerremark

🐛

novsirion

🐛

nwcm

📖 🐛

nwcm

📖 🐛

oggboy

🐛

oinume

🐛

orimarko

💻 🐛

pacvz

💻

pallavi agarwal

🐛

parksungrin

🐛

patpatpat123

🐛

patpatpat123

🐛

patriksevallius

🐛

pbrajesh1

🐛

phoenix384

🐛

piotrszymanski-sc

💻

plan3d

🐛

poojasix

🐛

prabhushrikant

🐛

prabhushrikant

🐛

pujitha8783

🐛

r-r-a-j

🐛

raghujayjunk

🐛

rajeshveera

🐛

rajeswarreddy88

🐛

recdevs

🐛

reudismam

💻 🐛

reudismam

💻 🐛

rijkt

🐛

rillig-tk

🐛

rmohan20

💻 🐛

rnveach

🐛

rxmicro

🐛

ryan-gustafson

💻 🐛

sabi0

🐛

sabi0

🐛

scais

🐛

sebbASF

🐛

sergeygorbaty

💻

shilko2013

🐛

shiomiyan

📖

simeonKondr

🐛

snajberk

🐛

snajberk

🐛

sniperrifle2004

🐛

snuyanzin

🐛 💻

sratz

🐛

stonio

🐛

sturton

💻 🐛

sudharmohan

🐛

suruchidawar

🐛

suruchidawar

🐛

svenfinitiv

🐛

tashiscool

🐛

test-git-hook

🐛

testation21

💻 🐛

thanosa

🐛

tiandiyixian

🐛

tobwoerk

🐛

tobwoerk

🐛

tprouvot

🐛 💻

trentchilders

🐛

triandicAnt

🐛

trishul14

🐛

tsui

🐛

winhkey

🐛

witherspore

🐛

witherspore

🐛

wjljack

🐛

wuchiuwong

🐛

xingsong

🐛

xioayuge

🐛

xnYi9wRezm

💻 🐛

xuanuy

🐛

xyf0921

🐛

xyf0921

🐛

yalechen-cyw3

🐛

yasuharu-sato

🐛

zenglian

🐛

zgrzyt93

💻 🐛

zh3ng

🐛

zt_soft

🐛

ztt79

🐛

ztt79

🐛

zzzzfeng

🐛

Árpád Magosányi

🐛

任贵杰

🐛

snajberk

🐛

sniperrifle2004

🐛

snuyanzin

🐛 💻

soyodream

🐛

sratz

🐛

stonio

🐛

sturton

💻 🐛

sudharmohan

🐛

sudharmohan

🐛

suruchidawar

🐛

svenfinitiv

🐛

tashiscool

🐛

test-git-hook

🐛

testation21

💻 🐛

thanosa

🐛

tiandiyixian

🐛

tiandiyixian

🐛

tobwoerk

🐛

tprouvot

🐛 💻

trentchilders

🐛

triandicAnt

🐛

trishul14

🐛

tsui

🐛

winhkey

🐛

winhkey

🐛

witherspore

🐛

wjljack

🐛

wuchiuwong

🐛

xingsong

🐛

xioayuge

🐛

xnYi9wRezm

💻 🐛

xuanuy

🐛

xuanuy

🐛

xyf0921

🐛

yalechen-cyw3

🐛

yasuharu-sato

🐛

zenglian

🐛

zgrzyt93

💻 🐛

zh3ng

🐛

zt_soft

🐛

zt_soft

🐛

ztt79

🐛

zzzzfeng

🐛

Árpád Magosányi

🐛

b-3-n

🐛

balbhadra9

🐛

base23de

🐛

bergander

🐛

bergander

🐛 💻

berkam

💻 🐛

Dawid Ciok

🐛 💻

Debamoy Datta

💻

Deleted user

🐛

Dell Green

🐛

Dem Pilafian

🐛

Den

🐛

Denis Borovikov

💻 🐛

Dennie Reniers

💻 🐛

Dennis Kieselhorst

🐛

Dennis Kieselhorst

🐛

Derek P. Moore

🐛

Dichotomia

🐛

Dionisio Cortés Fernández

💻 🐛

Dmitri Bourlatchkov

🐛

Dmitriy Kuzmin

🐛

Dmytro Dashenkov

🐛

Drew Hall

🐛

Drew Hall

🐛

Dumitru Postoronca

🐛

Dylan Adams

🐛

Eden Hao

🐛

Edward Klimoshenko

🐛 💻

Egor Bredikhin

🐛

Elan P. Kugelmass

🐛

Elder S.

🐛

Elder S.

🐛

Eldrick Wega

📖

Emile

🐛

Eric

🐛

Eric Kintzer

🐛

Eric Perret

🐛

Eric Squires

🐛

Erich L Foster

🐛

Erich L Foster

🐛

Erik Bleske

🐛

Ernst Reissner

🐛

Ewan Tempero

🐛

F.W. Dekker

🐛

FSchliephacke

🐛

Facundo

🐛

Federico Giust

🐛

Federico Giust

🐛

Fedor Sherstobitov

🐛

Felix Lampe

🐛

Filip Golonka

🐛

Filipe Esperandio

💻 🐛

Filippo Nova

🐛

Francesco la Torre

🐛

Francisco Duarte

🐛

Francisco Duarte

🐛

Frieder Bluemle

🐛

Frits Jalvingh

💻 🐛

G. Bazior

🐛

Gabe Henkes

🐛

Gary Gregory

🐛

Genoud Magloire

🐛

Geoffrey555

🐛

Geoffrey555

🐛

Georg Romstorfer

🐛

Gio

🐛

Gol

🐛

Gonzalo Exequiel Ibars Ingman

💻 🐛

GooDer

🐛

Gregor Riegler

🐛

Grzegorz Olszewski

🐛

Grzegorz Olszewski

🐛

Gunther Schrijvers

💻 🐛

Gustavo Krieger

🐛

Guy Elsmore-Paddock

🐛

Görkem Mülayim

🐛

Hanzel Godinez

🐛

Haoliang Chen

🐛

Harsh Kukreja

🐛

Harsh Kukreja

🐛

Hassan ALAMI

🐛

Heber

🐛

Henning Schmiedehausen

💻 🐛

Henning von Bargen

💻

Hervé Boutemy

🐛

Himanshu Pandey

🐛

Hokwang Lee

🐛

Hokwang Lee

🐛

Hooperbloob

💻

Hung PHAN

🐛

IDoCodingStuffs

💻 🐛

Iccen Gan

🐛

Ignacio Mariano Tirabasso

🐛

Igor Melnichenko

🐛

Igor Moreno

🐛

Igor Moreno

🐛

Intelesis-MS

🐛

Iroha_

🐛

Ishan Srivastava

🐛

Ivano Guerini

🐛

Ivar Andreas Bonsaksen

🐛

Ivo Šmíd

🐛

JJengility

🐛

JJengility

🐛

Jake Hemmerle

🐛

James Harrison

🐛 💻

Jan

🐛

Jan Aertgeerts

💻 🐛

Jan Brümmer

🐛

Jan Tříska

🐛

Jan-Lukas Else

🐛

Jan-Lukas Else

🐛

Jason Qiu

💻 📖

Jason Williams

🐛

Jean-Paul Mayer

🐛

Jean-Simon Larochelle

🐛

Jeff Bartolotta

💻 🐛

Jeff Hube

💻 🐛

Jeff Jensen

🐛

Jeff Jensen

🐛

Jeff May

🐛

Jens Gerdes

🐛

Jeroen Borgers

🐛 💻 📢

Jeroen van Wilgenburg

📖

Jerome Russ

🐛

JerritEic

💻 📖 🐛

Jiri Pejchal

🐛

Jiri Pejchal

🐛

Jithin Sunny

🐛

Jiří Škorpil

🐛

Joao Machado

🐛

Jochen Krauss

🐛

Johan Hammar

🐛

John Karp

🐛

John Zhang

🐛

John Zhang

🐛

John-Teng

💻 🐛

Jon Moroney

💻 🐛

Jonas Geiregat

🐛

Jonathan Wiesel

💻 🐛

Jordan

🐛

Jordi Llach

🐛

Jorge Solórzano

🐛

Jorge Solórzano

🐛

JorneVL

🐛

Jose Palafox

🐛

Jose Stovall

🐛

Joseph

💻

Joseph Heenan

🐛

Josh Feingold

💻 🐛

Josh Holthaus

🐛

Josh Holthaus

🐛

Joshua S Arquilevich

🐛

João Dinis Ferreira

📖

João Ferreira

💻 🐛

João Pedro Schmitt

🐛

Juan Martín Sotuyo Dodero

💻 📖 🐛 🚧

Juan Pablo Civile

🐛

Julian Voronetsky

🐛

Julian Voronetsky

🐛

Julien

🐛

Julius

🐛

JustPRV

🐛

Jörn Huxhorn

🐛

KThompso

🐛

Kai Amundsen

🐛

Karel Vervaeke

🐛

Karel Vervaeke

🐛

Karl-Andero Mere

🐛

Karl-Philipp Richter

🐛

Karsten Silz

🐛

Kazuma Watanabe

🐛

Kev

🐛

Keve Müller

🐛

Kevin Guerra

💻

Kevin Guerra

💻

Kevin Jones

🐛 💻

Kevin Wayne

🐛

Kieran Black

🐛

Kirill Zubov

🐛

Kirk Clemens

💻 🐛

Klaus Hartl

🐛

Koen Van Looveren

🐛

Koen Van Looveren

🐛

Kris Scheibe

💻 🐛

Krystian Dabrowski

🐛 💻

Kunal Thanki

🐛

LaLucid

💻

Larry Diamond

💻 🐛

Lars Knickrehm

🐛

Leo Gutierrez

🐛

Leo Gutierrez

🐛

LiGaOg

💻

Liam Sharp

🐛

Lintsi

🐛

Linus Fernandes

🐛

Lixon Lookose

🐛

Logesh

🐛

Lorenzo Gabriele

🐛

Lorenzo Gabriele

🐛

Loïc Ledoyen

🐛

Lucas Silva

🐛

Lucas Soncini

💻 🐛

Luis Alcantar

💻

Lukasz Slonina

🐛

Lukebray

🐛

Lynn

💻 🐛

Lynn

💻 🐛

Lyor Goldstein

🐛

MCMicS

🐛

Macarse

🐛

Machine account for PMD

💻

Maciek Siemczyk

🐛

Maikel Steneker

💻 🐛

Maksim Moiseikin

🐛

Maksim Moiseikin

🐛

Manfred Koch

🐛

Manuel Moya Ferrer

💻 🐛

Manuel Ryan

🐛

Marat Vyshegorodtsev

🐛

Marcel Härle

🐛

Marcello Fialho

🐛

Marcin Rataj

🐛

Marcin Rataj

🐛

Marcono1234

🐛

Mark Adamcin

🐛

Mark Hall

💻 🐛

Mark Kolich

🐛

Mark Pritchard

🐛

Markus Rathgeb

🐛

Marquis Wang

🐛

Marquis Wang

🐛

MartGit

🐛

Martin Feldsztejn

🐛

Martin Lehmann

🐛

Martin Spamer

🐛

Martin Tarjányi

🐛

MatFl

🐛

Mateusz Stefanski

🐛

Mateusz Stefanski

🐛

Mathieu Gouin

🐛

MatiasComercio

💻 🐛

Matt Benson

🐛

Matt De Poorter

🐛

Matt Hargett

💻 💵

Matt Harrah

🐛

Matt Nelson

🐛

Matt Nelson

🐛

Matthew Amos

🐛

Matthew Duggan

🐛

Matthew Hall

🐛

Matías Fraga

💻 🐛

Maxime Robert

💻 🐛

MetaBF

🐛

Michael

🐛

Michael

🐛

Michael Bell

🐛

Michael Bernstein

🐛

Michael Clay

🐛

Michael Dombrowski

🐛

Michael Hausegger

🐛

Michael Hoefer

🐛

Michael Möbius

🐛

Michael Möbius

🐛

Michael N. Lipp

🐛

Michael Pellegrini

🐛

Michal Kordas

🐛

Michał Borek

🐛

Michał Kuliński

🐛

Miguel Núñez Díaz-Montes

🐛

Mihai Ionut

🐛

Mihai Ionut

🐛

Mirek Hankus

🐛

Mladjan Gadzic

🐛

MrAngry52

🐛

Muminur Choudhury

🐛

Mykhailo Palahuta

💻 🐛

Nagendra Kumar Singh

🐛

Nahuel Barrios

🐛

Nahuel Barrios

🐛

Nathan Braun

🐛

Nathan Reynolds

🐛

Nathan Reynolds

🐛

Nathanaël

🐛

Naveen

💻

Nazdravi

🐛

Neha-Dhonde

🐛

Neha-Dhonde

🐛

Nicholas Doyle

🐛

Nick Butcher

🐛

Nico Gallinal

🐛

Nicola Dal Maso

🐛

Nicolas Filotto

💻

Nicolas Vervelle

🐛

Nicolas Vuillamy

📖

Nicolas Vuillamy

📖

Nikita Chursin

🐛

Niklas Baudy

🐛

Nikolas Havrikov

🐛

Nilesh Virkar

🐛

Nimit Patel

🐛

Niranjan Harpale

🐛

Nirvik Patel

💻

Nirvik Patel

💻

Noah Sussman

🐛

Noah0120

🐛

Noam Tamim

🐛

Noel Grandin

🐛

Olaf Haalstra

🐛

Oleg Andreych

💻 🐛

Oleg Pavlenko

🐛

Oleg Pavlenko

🐛

Oleksii Dykov

💻 🐛

Oliver Eikemeier

🐛

Oliver Siegmar

💵

Olivier Parent

💻 🐛

Ollie Abbey

💻 🐛

OverDrone

🐛

Ozan Gulle

💻 🐛

Ozan Gulle

💻 🐛

PUNEET JAIN

🐛

Parbati Bose

🐛

Paul Berg

🐛

Paul Guyot

💻

Pavel Bludov

🐛

Pavel Mička

🐛

Pedro Nuno Santos

🐛

Pedro Nuno Santos

🐛

Pedro Rijo

🐛

Pelisse Romain

💻 📖 🐛

Per Abich

💻

Pete Davids

🐛

Peter Bruin

🐛

Peter Chittum

💻 🐛

Peter Cudmore

🐛

Peter Cudmore

🐛

Peter Kasson

🐛

Peter Kofler

🐛

Peter Paul Bakker

💻

Pham Hai Trung

🐛

Philip Graf

💻 🐛

Philip Hachey

🐛

Philippe Ozil

🐛

Philippe Ozil

🐛

Phinehas Artemix

🐛

Phokham Nonava

🐛

Pim van der Loos

💻 ⚠️

Piotr Szymański

🐛

Piotrek Żygieło

💻 🐛 📖

Pranay Jaiswal

🐛

Prasad Kamath

🐛

Prasad Kamath

🐛

Prasanna

🐛

Presh-AR

🐛

Puneet1726

🐛

Rafael Cortês

🐛

RaheemShaik999

🐛

RajeshR

💻 🐛

Ramachandra Mohan

🐛

Ramachandra Mohan

🐛

Ramel0921

🐛

Raquel Pau

🐛

Ravikiran Janardhana

🐛

Reda Benhemmouche

🐛

Renato Oliveira

💻 🐛

Rich DiCroce

🐛

Richard Corfield

💻

Richard Corfield

💻

Richard Corfield

🐛 💻

Riot R1cket

🐛

Rishabh Jain

🐛

RishabhDeep Singh

🐛

Robbie Martinus

💻 🐛

Robert Henry

🐛

Robert Mihaly

🐛

Robert Mihaly

🐛

Robert Painsi

🐛

Robert Russell

🐛

Robert Sösemann

💻 📖 📢 🐛

Robert Whitebit

🐛

Robin Richtsfeld

🐛

Robin Stocker

💻 🐛

Robin Wils

🐛

Robin Wils

🐛

RochusOest

🐛

Rodolfo Noviski

🐛

Rodrigo Casara

🐛

Rodrigo Fernandes

🐛

Roman Salvador

💻 🐛

Ronald Blaschke

🐛

Róbert Papp

🐛

Róbert Papp

🐛

Saikat Sengupta

🐛

Saksham Handu

🐛

Saladoc

🐛

Salesforce Bob Lightning

🐛

Sam Carlberg

🐛

Satoshi Kubo

🐛

Scott Kennedy

🐛

Scott Kennedy

🐛

Scott Wells

🐛 💻

Scrsloota

💻

Sebastian Bögl

🐛

Sebastian Schuberth

🐛

Sebastian Schwarz

🐛

Seren

🐛 💻

Sergey Gorbaty

🐛

Sergey Gorbaty

🐛

Sergey Kozlov

🐛

Sergey Yanzin

💻 🐛

Seth Wilcox

💻

Shubham

💻 🐛

Simon Abykov

💻 🐛

Simon Xiao

🐛

Srinivasan Venkatachalam

🐛

Srinivasan Venkatachalam

🐛

Stanislav Gromov

🐛

Stanislav Myachenkov

💻

Stefan Birkner

🐛

Stefan Bohn

🐛

Stefan Endrullis

🐛

Stefan Klöss-Schuster

🐛

Stefan Wolf

🐛

Stefan Wolf

🐛

Stephan H. Wissel

🐛

Stephen

🐛

Stephen Friedrich

🐛

Steve Babula

💻

Steven Stearns

🐛 💻

Stexxe

🐛

Stian Lågstad

🐛

Stian Lågstad

🐛

StuartClayton5

🐛

Supun Arunoda

🐛

Suren Abrahamyan

🐛

Suvashri

📖

SwatiBGupta1110

🐛

SyedThoufich

🐛

Szymon Sasin

🐛

Szymon Sasin

🐛

T-chuangxin

🐛

TERAI Atsuhiro

🐛

TIOBE Software

💻 🐛

Tarush Singh

💻

Taylor Smock

🐛

Techeira Damián

💻 🐛

Ted Husted

🐛

Ted Husted

🐛

TehBakker

🐛

The Gitter Badger

🐛

Theodoor

🐛

Thiago Henrique Hüpner

🐛

Thibault Meyer

🐛

Thomas Güttler

🐛

Thomas Jones-Low

🐛

Thomas Jones-Low

🐛

Thomas Smith

💻 🐛

ThrawnCA

🐛

Thunderforge

💻 🐛

Tim van der Lippe

🐛

Tobias Weimer

💻 🐛

Tom Copeland

🐛 💻 📖

Tom Daly

🐛

Tom Daly

🐛

Tomer Figenblat

🐛

Tomi De Lucca

💻 🐛

Torsten Kleiber

🐛

TrackerSB

🐛

Tyson Stewart

🐛

Ullrich Hafner

🐛

Utku Cuhadaroglu

💻 🐛

Utku Cuhadaroglu

💻 🐛

Valentin Brandl

🐛

Valeria

🐛

Valery Yatsynovich

📖

Vasily Anisimov

🐛

Vibhor Goyal

🐛

Vickenty Fesunov

🐛

Victor Noël

🐛

Victor Noël

🐛

Vincent Galloy

💻

Vincent HUYNH

🐛

Vincent Maurin

🐛

Vincent Privat

🐛

Vishhwas

🐛

Vitaly

🐛

Vitaly Polonetsky

🐛

Vitaly Polonetsky

🐛

Vojtech Polivka

🐛

Vsevolod Zholobov

🐛

Vyom Yadav

💻

Wang Shidong

🐛

Waqas Ahmed

🐛

Wayne J. Earl

🐛

Wchenghui

🐛

Wchenghui

🐛

Wener

💻

Will Winder

🐛

William Brockhus

💻 🐛

Wilson Kurniawan

🐛

Wim Deblauwe

🐛

Woongsik Choi

🐛

XenoAmess

💻 🐛

XenoAmess

💻 🐛

Yang

💻

YaroslavTER

🐛

Yasar Shaikh

💻

Young Chan

💻 🐛

YuJin Kim

🐛

Yuri Dolzhenko

🐛

Yurii Dubinka

🐛

Yurii Dubinka

🐛

Zoltan Farkas

🐛

Zustin

🐛

aaronhurst-google

🐛 💻

alexmodis

🐛

andreoss

🐛

andrey81inmd

💻 🐛

anicoara

🐛

anicoara

🐛

arunprasathav

🐛

asiercamara

🐛

astillich-igniti

💻

avesolovksyy

🐛

avishvat

🐛

avivmu

🐛

axelbarfod1

🐛

axelbarfod1

🐛

b-3-n

🐛

balbhadra9

🐛

base23de

🐛

bergander

🐛

berkam

💻 🐛

breizh31

🐛

caesarkim

🐛

caesarkim

🐛

carolyujing

🐛

cbfiddle

🐛

cesares-basilico

🐛

chrite

🐛

cobratbq

🐛

coladict

🐛

cosmoJFH

🐛

cosmoJFH

🐛

cristalp

🐛

crunsk

🐛

cwholmes

🐛

cyberjj999

🐛

cyw3

🐛 📖

d1ss0nanz

🐛

dague1

📖

dague1

📖

dalizi007

💻

danbrycefairsailcom

🐛

dariansanity

🐛

darrenmiliband

🐛

davidburstrom

🐛

dbirkman-paloalto

🐛

deepak-patra

🐛

deepak-patra

🐛

dependabot[bot]

💻 🐛

dinesh150

🐛

diziaq

🐛

dreaminpast123

🐛

duanyanan

🐛

dutt-sanjay

🐛

dylanleung

🐛

dylanleung

🐛

dzeigler

🐛

eant60

🐛

ekkirala

🐛

emersonmoura

🐛

eugenepugach

🐛

fairy

🐛

filiprafalowicz

💻

filiprafalowicz

💻

foxmason

🐛

frankegabor

🐛

frankl

🐛

freafrea

🐛

fsapatin

🐛

gracia19

🐛

guo fei

🐛

guo fei

🐛

gurmsc5

🐛

gwilymatgearset

💻 🐛

haigsn

🐛

hemanshu070

🐛

henrik242

🐛

hongpuwu

🐛

hvbtup

💻 🐛

hvbtup

💻 🐛

igniti GmbH

🐛

ilovezfs

🐛

itaigilo

🐛

jakivey32

🐛

jbennett2091

🐛

jcamerin

🐛

jkeener1

🐛

jkeener1

🐛

jmetertea

🐛

johnra2

💻

josemanuelrolon

💻 🐛

kabroxiko

💻 🐛

karwer

🐛

kaulonline

🐛

kdaemonv

🐛

kdaemonv

🐛

kdebski85

🐛 💻

kenji21

💻 🐛

kfranic

🐛

khalidkh

🐛

koalalam

🐛

krzyk

🐛

lasselindqvist

🐛

lasselindqvist

🐛

lgemeinhardt

🐛

lihuaib

🐛

lonelyma1021

🐛

lpeddy

🐛

lujiefsi

💻

lukelukes

💻

lyriccoder

🐛

lyriccoder

🐛

marcelmore

🐛

matchbox

🐛

matthiaskraaz

🐛

meandonlyme

🐛

mikesive

🐛

milossesic

🐛

mluckam

💻

mluckam

💻

mohan-chinnappan-n

💻

mriddell95

🐛

mrlzh

🐛

msloan

🐛

mucharlaravalika

🐛

mvenneman

🐛

nareshl119

🐛

nareshl119

🐛

nicolas-harraudeau-sonarsource

🐛

noerremark

🐛

novsirion

🐛

nwcm

📖 🐛

oggboy

🐛

oinume

🐛

orimarko

💻 🐛

orimarko

💻 🐛

pacvz

💻

pallavi agarwal

🐛

parksungrin

🐛

patpatpat123

🐛

patriksevallius

🐛

pbrajesh1

🐛

phoenix384

🐛

phoenix384

🐛

piotrszymanski-sc

💻

plan3d

🐛

poojasix

🐛

prabhushrikant

🐛

pujitha8783

🐛

r-r-a-j

🐛

raghujayjunk

🐛

raghujayjunk

🐛

rajeshveera

🐛

rajeswarreddy88

🐛

recdevs

🐛

reudismam

💻 🐛

rijkt

🐛

rillig-tk

🐛

rmohan20

💻 🐛

rmohan20

💻 🐛

rnveach

🐛

rxmicro

🐛

ryan-gustafson

💻 🐛

sabi0

🐛

scais

🐛

sebbASF

🐛

sergeygorbaty

💻

sergeygorbaty

💻

shilko2013

🐛

shiomiyan

📖

simeonKondr

🐛

snajberk

🐛

sniperrifle2004

🐛

snuyanzin

🐛 💻

sratz

🐛

sratz

🐛

stonio

🐛

sturton

💻 🐛

sudharmohan

🐛

suruchidawar

🐛

svenfinitiv

🐛

tashiscool

🐛

test-git-hook

🐛

test-git-hook

🐛

testation21

💻 🐛

thanosa

🐛

tiandiyixian

🐛

tobwoerk

🐛

tprouvot

🐛 💻

trentchilders

🐛

triandicAnt

🐛

triandicAnt

🐛

trishul14

🐛

tsui

🐛

winhkey

🐛

witherspore

🐛

wjljack

🐛

wuchiuwong

🐛

xingsong

🐛

xingsong

🐛

xioayuge

🐛

xnYi9wRezm

💻 🐛

xuanuy

🐛

xyf0921

🐛

yalechen-cyw3

🐛

yasuharu-sato

🐛

zenglian

🐛

zenglian

🐛

zgrzyt93

💻 🐛

zh3ng

🐛

zt_soft

🐛

ztt79

🐛

zzzzfeng

🐛

Árpád Magosányi

🐛

任贵杰

🐛

任贵杰

🐛

茅延安

💻
From 990090d6d1c7d081e148b590390c8725823d7563 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Dec 2023 15:05:22 +0100 Subject: [PATCH 38/61] [doc] Update release notes (#4706, #1831) --- docs/pages/release_notes.md | 5 +++++ .../pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a892d43832..723d7743b8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -52,10 +52,13 @@ The remaining section describes the complete release notes for 7.0.0. * java-codestyle * [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types * [#4578](https://github.com/pmd/pmd/issues/4578): \[java] CommentDefaultAccessModifier comment needs to be before annotation if present +* java-errorprone + * [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods #### API Changes #### External Contributions +* [#4706](https://github.com/pmd/pmd/pull/4706): \[java] DetachedTestCase should not report on abstract methods - [Debamoy Datta](https://github.com/Debamoy) (@Debamoy) ### 🚀 Major Features and Enhancements @@ -599,6 +602,7 @@ Language specific fixes: * [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break * [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces * [#1669](https://github.com/pmd/pmd/issues/1669): \[java] NullAssignment - FP with ternay and null as constructor argument + * [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods * [#1899](https://github.com/pmd/pmd/issues/1899): \[java] Recognize @SuppressWanings("fallthrough") for MissingBreakInSwitch * [#2320](https://github.com/pmd/pmd/issues/2320): \[java] NullAssignment - FP with ternary and null as method argument * [#2532](https://github.com/pmd/pmd/issues/2532): \[java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case `new BigDecimal(Expression)` @@ -685,6 +689,7 @@ Language specific fixes: * [#4651](https://github.com/pmd/pmd/pull/4651): \[doc] Add "Tencent Cloud Code Analysis" in Tools / Integrations - [yale](https://github.com/cyw3) (@cyw3) * [#4664](https://github.com/pmd/pmd/pull/4664): \[cli] CPD: Fix NPE when only `--file-list` is specified - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) * [#4665](https://github.com/pmd/pmd/pull/4665): \[java] Doc: Fix references AutoClosable -> AutoCloseable - [Andrey Bozhko](https://github.com/AndreyBozhko) (@AndreyBozhko) +* [#4706](https://github.com/pmd/pmd/pull/4706): \[java] DetachedTestCase should not report on abstract methods - [Debamoy Datta](https://github.com/Debamoy) (@Debamoy) ### 📈 Stats * 5007 commits diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml index 086d3848db..b6f51a648a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DetachedTestCase.xml @@ -37,7 +37,7 @@ public class MyTest { - Abstract methods should not be reported as detached test case + Abstract methods should not be reported as detached test case (#1831) 0 Date: Mon, 20 Nov 2023 13:21:50 +0100 Subject: [PATCH 39/61] Fix NoSuchMethodError on processing errors in pmd-compat6 --- .../src/it/pmd-for-java/exception_ruleset.xml | 16 ++++++++++++++++ pmd-compat6/src/it/pmd-for-java/pom.xml | 6 +++++- pmd-compat6/src/it/pmd-for-java/verify.bsh | 4 ++++ .../main/java/net/sourceforge/pmd/Report.java | 5 +++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml diff --git a/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml b/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml new file mode 100644 index 0000000000..7f9604ffa3 --- /dev/null +++ b/pmd-compat6/src/it/pmd-for-java/exception_ruleset.xml @@ -0,0 +1,16 @@ + + + + Use this rule to produce a processing error. + 3 + + + + + + + diff --git a/pmd-compat6/src/it/pmd-for-java/pom.xml b/pmd-compat6/src/it/pmd-for-java/pom.xml index 32991b1ba3..55682ec03b 100644 --- a/pmd-compat6/src/it/pmd-for-java/pom.xml +++ b/pmd-compat6/src/it/pmd-for-java/pom.xml @@ -30,8 +30,12 @@ true - false + true 5 + + /rulesets/java/maven-pmd-plugin-default.xml + ${project.basedir}/exception_ruleset.xml + diff --git a/pmd-compat6/src/it/pmd-for-java/verify.bsh b/pmd-compat6/src/it/pmd-for-java/verify.bsh index f0325f4c97..7f8e915e13 100644 --- a/pmd-compat6/src/it/pmd-for-java/verify.bsh +++ b/pmd-compat6/src/it/pmd-for-java/verify.bsh @@ -51,3 +51,7 @@ String textReport = readFile(pmdTextReport); if (!textReport.contains(mainFile + ":5:\tUnusedLocalVariable")) { throw new RuntimeException("Expected violation has not been reported in TXT"); } + +if (!pmdXml.contains(" Date: Fri, 29 Sep 2023 15:24:43 +0200 Subject: [PATCH 40/61] Add swift 5.9 support --- .../ast/impl/antlr4/AntlrNameDictionary.java | 1 + .../pmd/it/BinaryDistributionIT.java | 2 +- .../sourceforge/pmd/lang/swift/ast/Swift.g4 | 5 + .../pmd/lang/swift/SwiftLanguageModule.java | 4 +- .../lang/swift/cpd/SwiftTokenizerTest.java | 5 + .../lang/swift/cpd/testdata/Swift5.9.swift | 43 ++++ .../pmd/lang/swift/cpd/testdata/Swift5.9.txt | 217 ++++++++++++++++++ 7 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.swift create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.txt diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java index 1ca4c4f953..ffbf2e29cc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java @@ -122,6 +122,7 @@ public class AntlrNameDictionary { case "@": return "at-symbol"; case "$": return "dollar"; + case "#": return "hash"; case "\\": return "backslash"; case "/": return "slash"; diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java index 86bb126f76..57c5de0638 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java @@ -60,7 +60,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "scala-2.10", "scala-2.11", "scala-2.12", "scala-2.13", "swift-4.2", "swift-5.0", "swift-5.1", "swift-5.2", "swift-5.3", "swift-5.4", "swift-5.5", "swift-5.6", - "swift-5.7", "vf-52", "vf-53", "vf-54", "vf-55", "vf-56", + "swift-5.7", "swift-5.8", "swift-5.9", "vf-52", "vf-53", "vf-54", "vf-55", "vf-56", "vf-57", "vf-58", "vf-59", "vm-2.0", "vm-2.1", "vm-2.2", "vm-2.3", "wsdl-1.1", "wsdl-2.0", "xml-1.0", "xml-1.1", "xsl-1.0", "xsl-2.0", diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 index 17c2e3f934..d997b621fa 100644 --- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 +++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 @@ -211,6 +211,7 @@ declaration | constantDeclaration ';'? | variableDeclaration ';'? | typealiasDeclaration ';'? + | macroExpansionExpression ';'? | functionDeclaration ';'? | enumDeclaration ';'? | structDeclaration ';'? @@ -297,6 +298,10 @@ typealiasHead : attributes? accessLevelModifier? 'typealias' typealiasName gener typealiasName : identifier ; typealiasAssignment : '=' sType ; +// GRAMMAR OF A MACRO DECLARATION + +macroExpansionExpression: '#' identifier genericArgumentClause? functionCallArgumentClause? ; + // GRAMMAR OF A FUNCTION DECLARATION /* HACK: functionBody? is intentionally not used to force the parser to try and match a functionBody first diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java index 2a46c9cd0f..bda47e0ba5 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java @@ -30,7 +30,9 @@ public class SwiftLanguageModule extends SimpleLanguageModuleBase { .addVersion("5.4") .addVersion("5.5") .addVersion("5.6") - .addDefaultVersion("5.7"), + .addVersion("5.7") + .addVersion("5.8") + .addDefaultVersion("5.9"), new SwiftHandler()); } diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftTokenizerTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftTokenizerTest.java index ddb0949604..e3a3c19ab8 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftTokenizerTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftTokenizerTest.java @@ -50,6 +50,11 @@ class SwiftTokenizerTest extends CpdTextComparisonTest { doTest("Swift5.6"); } + @Test + void testSwift59() { + doTest("Swift5.9"); + } + @Test void testStackoverflowOnLongLiteral() { doTest("Issue628"); diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.swift new file mode 100644 index 0000000000..f0b3c0663e --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.swift @@ -0,0 +1,43 @@ +import SwiftUI + +struct ContentView: View { + var body: some View { + TabBarView() + } +} + +#Preview { + ContentView() +} + +// Macro Expansion: https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion +let _: Font = #fontLiteral(name: "SF Mono", size: 14, weight: .regular) + +// Parameter packs +func all(_ optional: repeat (each Wrapped)?) -> (repeat each Wrapped)? + +func useAll() { + if let (int, double, string, bool) = all(optionalInt, optionalDouble, optionalString, optionalBool) { + print(int, double, string, bool) + } + else { + print("got a nil") + } +} + +// return value on if/else if/else +statusBar.text = if !hasConnection { "Disconnected" } + else if let error = lastError { error.localizedDescription } + else { "Ready" } + +// https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/ +@attached(member) +@attached(conformance) +public macro OptionSet() = #externalMacro(module: "SwiftMacros", type: "OptionSetMacro") + +import SwiftUI + +#Preview { + Text() + .padding() +} diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.txt new file mode 100644 index 0000000000..ce130a0f84 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.9.txt @@ -0,0 +1,217 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [import] 1 7 + [SwiftUI] 8 15 +L3 + [struct] 1 7 + [ContentView] 8 19 + [:] 19 20 + [View] 21 25 + [{] 26 27 +L4 + [var] 5 8 + [body] 9 13 + [:] 13 14 + [some] 15 19 + [View] 20 24 + [{] 25 26 +L5 + [TabBarView] 9 19 + [(] 19 20 + [)] 20 21 +L6 + [}] 5 6 +L7 + [}] 1 2 +L9 + [#] 1 2 + [Preview] 2 9 + [{] 10 11 +L10 + [ContentView] 5 16 + [(] 16 17 + [)] 17 18 +L11 + [}] 1 2 +L14 + [let] 1 4 + [_] 5 6 + [:] 6 7 + [Font] 8 12 + [=] 13 14 + [#] 15 16 + [fontLiteral] 16 27 + [(] 27 28 + [name] 28 32 + [:] 32 33 + ["SF Mono"] 34 43 + [,] 43 44 + [size] 45 49 + [:] 49 50 + [14] 51 53 + [,] 53 54 + [weight] 55 61 + [:] 61 62 + [.] 63 64 + [regular] 64 71 + [)] 71 72 +L17 + [func] 1 5 + [all] 6 9 + [<] 9 10 + [each] 10 14 + [Wrapped] 15 22 + [>] 22 23 + [(] 23 24 + [_] 24 25 + [optional] 26 34 + [:] 34 35 + [repeat] 36 42 + [(] 43 44 + [each] 44 48 + [Wrapped] 49 56 + [)] 56 57 + [?] 57 58 + [)] 58 59 + [->] 60 62 + [(] 63 64 + [repeat] 64 70 + [each] 71 75 + [Wrapped] 76 83 + [)] 83 84 + [?] 84 85 +L19 + [func] 1 5 + [useAll] 6 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 +L20 + [if] 5 7 + [let] 8 11 + [(] 12 13 + [int] 13 16 + [,] 16 17 + [double] 18 24 + [,] 24 25 + [string] 26 32 + [,] 32 33 + [bool] 34 38 + [)] 38 39 + [=] 40 41 + [all] 42 45 + [(] 45 46 + [optionalInt] 46 57 + [,] 57 58 + [optionalDouble] 59 73 + [,] 73 74 + [optionalString] 75 89 + [,] 89 90 + [optionalBool] 91 103 + [)] 103 104 + [{] 105 106 +L21 + [print] 9 14 + [(] 14 15 + [int] 15 18 + [,] 18 19 + [double] 20 26 + [,] 26 27 + [string] 28 34 + [,] 34 35 + [bool] 36 40 + [)] 40 41 +L22 + [}] 5 6 +L23 + [else] 5 9 + [{] 10 11 +L24 + [print] 9 14 + [(] 14 15 + ["got a nil"] 15 26 + [)] 26 27 +L25 + [}] 5 6 +L26 + [}] 1 2 +L29 + [statusBar] 1 10 + [.] 10 11 + [text] 11 15 + [=] 16 17 + [if] 18 20 + [!] 21 22 + [hasConnection] 22 35 + [{] 36 37 + ["Disconnected"] 38 52 + [}] 53 54 +L30 + [else] 18 22 + [if] 23 25 + [let] 26 29 + [error] 30 35 + [=] 36 37 + [lastError] 38 47 + [{] 48 49 + [error] 50 55 + [.] 55 56 + [localizedDescription] 56 76 + [}] 77 78 +L31 + [else] 18 22 + [{] 23 24 + ["Ready"] 25 32 + [}] 33 34 +L34 + [@] 1 2 + [attached] 2 10 + [(] 10 11 + [member] 11 17 + [)] 17 18 +L35 + [@] 1 2 + [attached] 2 10 + [(] 10 11 + [conformance] 11 22 + [)] 22 23 +L36 + [public] 1 7 + [macro] 8 13 + [OptionSet] 14 23 + [<] 23 24 + [RawType] 24 31 + [>] 31 32 + [(] 32 33 + [)] 33 34 + [=] 35 36 + [#] 37 38 + [externalMacro] 38 51 + [(] 51 52 + [module] 52 58 + [:] 58 59 + ["SwiftMacros"] 60 73 + [,] 73 74 + [type] 75 79 + [:] 79 80 + ["OptionSetMacro"] 81 97 + [)] 97 98 +L38 + [import] 1 7 + [SwiftUI] 8 15 +L40 + [#] 1 2 + [Preview] 2 9 + [{] 10 11 +L41 + [Text] 5 9 + [(] 9 10 + [)] 10 11 +L42 + [.] 5 6 + [padding] 6 13 + [(] 13 14 + [)] 14 15 +L43 + [}] 1 2 +EOF From 6d09555af6d76993d22f5330e49f6c6deb4c3c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20D=C4=85browski?= Date: Mon, 4 Dec 2023 12:05:45 +0100 Subject: [PATCH 41/61] fix: remove delimiter attribute from pmd-java/src/main/resources/category/java/errorprone.xml When using `category/java/errorprone.xml` ruleset with PMD 7.0.0-rc4 I'm getting these warnings: ``` Warning at category/java/errorprone.xml:1039:78 1037| 1038| 1039| ^^^^^^^^^ Delimiter attribute is not supported anymore, values are always comma-separated. 1040| java.lang.Enum,java.lang.Class 1041| Warning at category/java/errorprone.xml:2353:62 2351| 3 2352| 2353| ^^^^^^^^^ Delimiter attribute is not supported anymore, values are always comma-separated. 2354| 2355| ``` --- pmd-java/src/main/resources/category/java/errorprone.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 8b9168bb57..2c4d7bf423 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1036,7 +1036,7 @@ in the `typesThatCompareByReference` property. 3 - + java.lang.Enum,java.lang.Class @@ -2350,7 +2350,7 @@ See the property `annotations`. 3 - + Date: Thu, 7 Dec 2023 18:18:43 +0100 Subject: [PATCH 42/61] [doc] Update release notes (#4642) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 71f4e34bdb..d15af94e5d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -102,6 +102,7 @@ in the Migration Guide. * miscellaneous * [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21 * [#4586](https://github.com/pmd/pmd/pull/4586): Use explicit encoding in ruleset xml files + * [#4642](https://github.com/pmd/pmd/issues/4642): Update regression tests with Java 21 language features * [#4741](https://github.com/pmd/pmd/pull/4741): Add pmd-compat6 module for maven-pmd-plugin * apex-performance * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop @@ -491,6 +492,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4460](https://github.com/pmd/pmd/pull/4460): Fix assembly-plugin warnings * [#4582](https://github.com/pmd/pmd/issues/4582): \[dist] Download link broken * [#4586](https://github.com/pmd/pmd/pull/4586): Use explicit encoding in ruleset xml files + * [#4642](https://github.com/pmd/pmd/issues/4642): Update regression tests with Java 21 language features * [#4691](https://github.com/pmd/pmd/issues/4691): \[CVEs] Critical and High CEVs reported on PMD and PMD dependencies * [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21 * [#4741](https://github.com/pmd/pmd/pull/4741): Add pmd-compat6 module for maven-pmd-plugin From 272b23d7b2e50db0b7930e6b82877e4fd7f7c204 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Dec 2023 18:43:34 +0100 Subject: [PATCH 43/61] [doc] Update release notes (#4759) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 71f4e34bdb..bd96fea47d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -145,6 +145,7 @@ The following previously deprecated classes have been removed: * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer - [219sansim](https://github.com/219sansim) (@219sansim) * [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property - [Andreas Bergander](https://github.com/bergander) (@bergander) +* [#4759](https://github.com/pmd/pmd/pull/4759): \[java] fix: remove delimiter attribute from ruleset category/java/errorprone.xml - [Marcin Dąbrowski](https://github.com/marcindabrowski) (@marcindabrowski) ### 🚀 Major Features and Enhancements @@ -810,6 +811,7 @@ Language specific fixes: * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer - [219sansim](https://github.com/219sansim) (@219sansim) * [#4754](https://github.com/pmd/pmd/pull/4754): \[java] EmptyControlStatementRule: Add allowCommentedBlocks property - [Andreas Bergander](https://github.com/bergander) (@bergander) +* [#4759](https://github.com/pmd/pmd/pull/4759): \[java] fix: remove delimiter attribute from ruleset category/java/errorprone.xml - [Marcin Dąbrowski](https://github.com/marcindabrowski) (@marcindabrowski) ### 📈 Stats * 5007 commits From 9f9a8f70687da9eb7987b9c6a9b25a4a57f8bdf7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Dec 2023 18:43:52 +0100 Subject: [PATCH 44/61] Add @marcindabrowski as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 129 +++++++++++++------------- 2 files changed, 75 insertions(+), 63 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f1dc6da997..0fe26264d9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7324,6 +7324,15 @@ "contributions": [ "code" ] + }, + { + "login": "marcindabrowski", + "name": "Marcin Dąbrowski", + "avatar_url": "https://avatars.githubusercontent.com/u/3007876?v=4", + "profile": "https://github.com/marcindabrowski", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 3bc7048d5d..7e5032fad6 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -466,577 +466,580 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Marcel Härle

🐛
Marcello Fialho

🐛 +
Marcin Dąbrowski

💻
Marcin Rataj

🐛
Marcono1234

🐛
Mark Adamcin

🐛
Mark Hall

💻 🐛 -
Mark Kolich

🐛 +
Mark Kolich

🐛
Mark Pritchard

🐛
Markus Rathgeb

🐛
Marquis Wang

🐛
MartGit

🐛
Martin Feldsztejn

🐛
Martin Lehmann

🐛 -
Martin Spamer

🐛 +
Martin Spamer

🐛
Martin Tarjányi

🐛
MatFl

🐛
Mateusz Stefanski

🐛
Mathieu Gouin

🐛
MatiasComercio

💻 🐛
Matt Benson

🐛 -
Matt De Poorter

🐛 +
Matt De Poorter

🐛
Matt Hargett

💻 💵
Matt Harrah

🐛
Matt Nelson

🐛
Matthew Amos

🐛
Matthew Duggan

🐛
Matthew Hall

🐛 -
Matías Fraga

💻 🐛 +
Matías Fraga

💻 🐛
Maxime Robert

💻 🐛
MetaBF

🐛
Michael

🐛
Michael Bell

🐛
Michael Bernstein

🐛
Michael Clay

🐛 -
Michael Dombrowski

🐛 +
Michael Dombrowski

🐛
Michael Hausegger

🐛
Michael Hoefer

🐛
Michael Möbius

🐛
Michael N. Lipp

🐛
Michael Pellegrini

🐛
Michal Kordas

🐛 -
Michał Borek

🐛 +
Michał Borek

🐛
Michał Kuliński

🐛
Miguel Núñez Díaz-Montes

🐛
Mihai Ionut

🐛
Mirek Hankus

🐛
Mladjan Gadzic

🐛
MrAngry52

🐛 -
Muminur Choudhury

🐛 +
Muminur Choudhury

🐛
Mykhailo Palahuta

💻 🐛
Nagendra Kumar Singh

🐛
Nahuel Barrios

🐛
Nathan Braun

🐛
Nathan Reynolds

🐛
Nathan Reynolds

🐛 -
Nathanaël

🐛 +
Nathanaël

🐛
Naveen

💻
Nazdravi

🐛
Neha-Dhonde

🐛
Nicholas Doyle

🐛
Nick Butcher

🐛
Nico Gallinal

🐛 -
Nicola Dal Maso

🐛 +
Nicola Dal Maso

🐛
Nicolas Filotto

💻
Nicolas Vervelle

🐛
Nicolas Vuillamy

📖
Nikita Chursin

🐛
Niklas Baudy

🐛
Nikolas Havrikov

🐛 -
Nilesh Virkar

🐛 +
Nilesh Virkar

🐛
Nimit Patel

🐛
Niranjan Harpale

🐛
Nirvik Patel

💻
Noah Sussman

🐛
Noah0120

🐛
Noam Tamim

🐛 -
Noel Grandin

🐛 +
Noel Grandin

🐛
Olaf Haalstra

🐛
Oleg Andreych

💻 🐛
Oleg Pavlenko

🐛
Oleksii Dykov

💻 🐛
Oliver Eikemeier

🐛
Oliver Siegmar

💵 -
Olivier Parent

💻 🐛 +
Olivier Parent

💻 🐛
Ollie Abbey

💻 🐛
OverDrone

🐛
Ozan Gulle

💻 🐛
PUNEET JAIN

🐛
Parbati Bose

🐛
Paul Berg

🐛 -
Paul Guyot

💻 +
Paul Guyot

💻
Pavel Bludov

🐛
Pavel Mička

🐛
Pedro Nuno Santos

🐛
Pedro Rijo

🐛
Pelisse Romain

💻 📖 🐛
Per Abich

💻 -
Pete Davids

🐛 +
Pete Davids

🐛
Peter Bruin

🐛
Peter Chittum

💻 🐛
Peter Cudmore

🐛
Peter Kasson

🐛
Peter Kofler

🐛
Peter Paul Bakker

💻 -
Pham Hai Trung

🐛 +
Pham Hai Trung

🐛
Philip Graf

💻 🐛
Philip Hachey

🐛
Philippe Ozil

🐛
Phinehas Artemix

🐛
Phokham Nonava

🐛
Pim van der Loos

💻 ⚠️ -
Piotr Szymański

🐛 +
Piotr Szymański

🐛
Piotrek Żygieło

💻 🐛 📖
Pranay Jaiswal

🐛
Prasad Kamath

🐛
Prasanna

🐛
Presh-AR

🐛
Puneet1726

🐛 -
Rafael Cortês

🐛 +
Rafael Cortês

🐛
RaheemShaik999

🐛
RajeshR

💻 🐛
Ramachandra Mohan

🐛
Ramel0921

🐛
Raquel Pau

🐛
Ravikiran Janardhana

🐛 -
Reda Benhemmouche

🐛 +
Reda Benhemmouche

🐛
Renato Oliveira

💻 🐛
Rich DiCroce

🐛
Richard Corfield

💻
Richard Corfield

🐛 💻
Riot R1cket

🐛
Rishabh Jain

🐛 -
RishabhDeep Singh

🐛 +
RishabhDeep Singh

🐛
Robbie Martinus

💻 🐛
Robert Henry

🐛
Robert Mihaly

🐛
Robert Painsi

🐛
Robert Russell

🐛
Robert Sösemann

💻 📖 📢 🐛 -
Robert Whitebit

🐛 +
Robert Whitebit

🐛
Robin Richtsfeld

🐛
Robin Stocker

💻 🐛
Robin Wils

🐛
RochusOest

🐛
Rodolfo Noviski

🐛
Rodrigo Casara

🐛 -
Rodrigo Fernandes

🐛 +
Rodrigo Fernandes

🐛
Roman Salvador

💻 🐛
Ronald Blaschke

🐛
Róbert Papp

🐛
Saikat Sengupta

🐛
Saksham Handu

🐛
Saladoc

🐛 -
Salesforce Bob Lightning

🐛 +
Salesforce Bob Lightning

🐛
Sam Carlberg

🐛
Satoshi Kubo

🐛
Scott Kennedy

🐛
Scott Wells

🐛 💻
Scrsloota

💻
Sebastian Bögl

🐛 -
Sebastian Schuberth

🐛 +
Sebastian Schuberth

🐛
Sebastian Schwarz

🐛
Seren

🐛 💻
Sergey Gorbaty

🐛
Sergey Kozlov

🐛
Sergey Yanzin

💻 🐛
Seth Wilcox

💻 -
Shai Bennathan

🐛 💻 +
Shai Bennathan

🐛 💻
Shubham

💻 🐛
Simon Abykov

💻 🐛
Simon Xiao

🐛
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛
Stanislav Myachenkov

💻 -
Stefan Birkner

🐛 +
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛
Stefan Klöss-Schuster

🐛
Stefan Wolf

🐛
Stephan H. Wissel

🐛
Stephen

🐛 -
Stephen Friedrich

🐛 +
Stephen Friedrich

🐛
Steve Babula

💻
Steven Stearns

🐛 💻
Stexxe

🐛
Stian Lågstad

🐛
StuartClayton5

🐛
Supun Arunoda

🐛 -
Suren Abrahamyan

🐛 +
Suren Abrahamyan

🐛
Suvashri

📖
SwatiBGupta1110

🐛
SyedThoufich

🐛
Szymon Sasin

🐛
T-chuangxin

🐛
TERAI Atsuhiro

🐛 -
TIOBE Software

💻 🐛 +
TIOBE Software

💻 🐛
Tarush Singh

💻
Taylor Smock

🐛
Techeira Damián

💻 🐛
Ted Husted

🐛
TehBakker

🐛
The Gitter Badger

🐛 -
Theodoor

🐛 +
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛
ThrawnCA

🐛 -
Thunderforge

💻 🐛 +
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Copeland

🐛 💻 📖
Tom Daly

🐛
Tomer Figenblat

🐛
Tomi De Lucca

💻 🐛 -
Torsten Kleiber

🐛 +
Torsten Kleiber

🐛
TrackerSB

🐛
Tyson Stewart

🐛
Ullrich Hafner

🐛
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛
Valeria

🐛 -
Valery Yatsynovich

📖 +
Valery Yatsynovich

📖
Vasily Anisimov

🐛
Vibhor Goyal

🐛
Vickenty Fesunov

🐛
Victor Noël

🐛
Vincent Galloy

💻
Vincent HUYNH

🐛 -
Vincent Maurin

🐛 +
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛
Vitaly

🐛
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛
Vsevolod Zholobov

🐛 -
Vyom Yadav

💻 +
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛
Wayne J. Earl

🐛
Wchenghui

🐛
Wener

💻
Will Winder

🐛 -
William Brockhus

💻 🐛 +
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛
XenoAmess

💻 🐛
Yang

💻
YaroslavTER

🐛 -
Yasar Shaikh

💻 +
Yasar Shaikh

💻
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛
Yurii Dubinka

🐛
Zoltan Farkas

🐛
Zustin

🐛 -
aaronhurst-google

🐛 💻 +
aaronhurst-google

🐛 💻
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛
anicoara

🐛
arunprasathav

🐛
asiercamara

🐛 -
astillich-igniti

💻 +
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛
axelbarfod1

🐛
b-3-n

🐛
balbhadra9

🐛 -
base23de

🐛 +
base23de

🐛
bergander

🐛 💻
berkam

💻 🐛
breizh31

🐛
caesarkim

🐛
carolyujing

🐛
cbfiddle

🐛 -
cesares-basilico

🐛 +
cesares-basilico

🐛
chrite

🐛
ciufudean

📖
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛
cristalp

🐛 -
crunsk

🐛 +
crunsk

🐛
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛 📖
d1ss0nanz

🐛
dague1

📖
dalizi007

💻 -
danbrycefairsailcom

🐛 +
danbrycefairsailcom

🐛
dariansanity

🐛
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛 -
dinesh150

🐛 +
dinesh150

🐛
diziaq

🐛
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛 -
eant60

🐛 +
eant60

🐛
ekkirala

🐛
emersonmoura

🐛
eugenepugach

🐛
fairy

🐛
filiprafalowicz

💻
foxmason

🐛 -
frankegabor

🐛 +
frankegabor

🐛
frankl

🐛
freafrea

🐛
fsapatin

🐛
gracia19

🐛
guo fei

🐛
gurmsc5

🐛 -
gwilymatgearset

💻 🐛 +
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛
henrik242

🐛
hongpuwu

🐛
hvbtup

💻 🐛
igniti GmbH

🐛 -
ilovezfs

🐛 +
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛
jbennett2091

🐛
jcamerin

🐛
jkeener1

🐛
jmetertea

🐛 -
johnra2

💻 +
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛
karwer

🐛
kaulonline

🐛
kdaemonv

🐛
kdebski85

🐛 💻 -
kenji21

💻 🐛 +
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛
koalalam

🐛
krzyk

🐛
lasselindqvist

🐛
lgemeinhardt

🐛 -
lihuaib

🐛 +
lihuaib

🐛
lonelyma1021

🐛
lpeddy

🐛
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛 -
matchbox

🐛 +
matchbox

🐛
matthiaskraaz

🐛
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mluckam

💻
mohan-chinnappan-n

💻 -
mriddell95

🐛 +
mriddell95

🐛
mrlzh

🐛
msloan

🐛
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛 -
noerremark

🐛 +
noerremark

🐛
novsirion

🐛
nwcm

📖 🐛
oggboy

🐛
oinume

🐛
orimarko

💻 🐛
pacvz

💻 -
pallavi agarwal

🐛 +
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻 -
plan3d

🐛 +
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛 -
rajeswarreddy88

🐛 +
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛
rillig-tk

🐛
rmohan20

💻 🐛
rnveach

🐛 -
rxmicro

🐛 +
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛 -
shiomiyan

📖 +
shiomiyan

📖
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻
soyodream

🐛
sratz

🐛 -
stonio

🐛 +
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛 -
testation21

💻 🐛 +
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛 💻
trentchilders

🐛
triandicAnt

🐛 -
trishul14

🐛 +
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛 -
xioayuge

🐛 +
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛 -
zgrzyt93

💻 🐛 +
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛
Árpád Magosányi

🐛
任贵杰

🐛 + +
茅延安

💻 From aa93a75009c2022d4406c29b200c2c99a6bd5a9a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Dec 2023 18:44:41 +0100 Subject: [PATCH 45/61] [test] Test built-in rulesets for warnings while loading --- .../log/internal/MessageReporterBase.java | 2 +- .../pmd/AbstractRuleSetFactoryTest.java | 21 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/MessageReporterBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/MessageReporterBase.java index 5b7e578592..e0929ac7d5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/MessageReporterBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/MessageReporterBase.java @@ -21,7 +21,7 @@ import net.sourceforge.pmd.util.log.MessageReporter; * * @author Clément Fournier */ -abstract class MessageReporterBase implements MessageReporter { +public abstract class MessageReporterBase implements MessageReporter { private int numErrors; private @Nullable Level minLevel = Level.TRACE; diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java index 8cb298bc32..dd5f81745c 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.emptyString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -34,6 +36,7 @@ import javax.xml.parsers.SAXParserFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.event.Level; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; @@ -45,6 +48,7 @@ import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.util.log.internal.MessageReporterBase; /** * Base test class to verify the language's rulesets. This class should be @@ -344,7 +348,22 @@ public abstract class AbstractRuleSetFactoryTest { } private RuleSet loadRuleSetByFileName(String ruleSetFileName) { - return new RuleSetLoader().loadFromResource(ruleSetFileName); + final StringBuilder messages = new StringBuilder(); + class Reporter extends MessageReporterBase { + @Override + protected void logImpl(Level level, String message) { + messages.append(message).append(System.lineSeparator()); + } + } + + RuleSet ruleSet = new RuleSetLoader() + .withReporter(new Reporter()) + .loadFromResource(ruleSetFileName); + + assertThat("There should be no warnings while loading the ruleset", + messages.toString(), emptyString()); + + return ruleSet; } private boolean validateAgainstSchema(String fileName) throws IOException, SAXException { From 49e6777fff0671c092306d610d3f52ee6cd2a120 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Dec 2023 18:56:27 +0100 Subject: [PATCH 46/61] [apex] Remove deprecated rule ref to ApexCSRF This rule has been moved from security to errorprone since PMD 6.21.0 already --- docs/pages/release_notes_pmd7.md | 1 + pmd-apex/src/main/resources/category/apex/security.xml | 2 -- pmd-apex/src/main/resources/rulesets/apex/security.xml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 6ec4ba8b3f..d3cd2f8dad 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -430,6 +430,7 @@ The following previously deprecated rules have been finally removed: * {% deleted_rule apex/codestyle/VariableNamingConventions %} ➡️ use {% rule apex/codestyle/FieldNamingConventions %}, {% rule apex/codestyle/FormalParameterNamingConventions %}, {% rule apex/codestyle/LocalVariableNamingConventions %}, or {% rule apex/codestyle/PropertyNamingConventions %} +* {% deleted_rule apex/security/ApexCSRF %} ➡️ use {% rule apex/errorprone/ApexCSRF %} **Java** diff --git a/pmd-apex/src/main/resources/category/apex/security.xml b/pmd-apex/src/main/resources/category/apex/security.xml index ca090afc48..8b93144c9d 100644 --- a/pmd-apex/src/main/resources/category/apex/security.xml +++ b/pmd-apex/src/main/resources/category/apex/security.xml @@ -120,8 +120,6 @@ public class Foo { - - - + From dcdab9d792ddd68a341a2e7ffde4dd207f8d665f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Dec 2023 20:05:35 +0100 Subject: [PATCH 47/61] Fix test --- pmd-compat6/src/it/pmd-for-java/verify.bsh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pmd-compat6/src/it/pmd-for-java/verify.bsh b/pmd-compat6/src/it/pmd-for-java/verify.bsh index 7f8e915e13..43e010d774 100644 --- a/pmd-compat6/src/it/pmd-for-java/verify.bsh +++ b/pmd-compat6/src/it/pmd-for-java/verify.bsh @@ -29,10 +29,13 @@ String pmdXml = readFile(pmdXmlReport); if (!pmdXml.contains("")) { throw new RuntimeException("Expected violation has not been reported"); } +if (!pmdXml.contains(" Date: Thu, 7 Dec 2023 20:08:16 +0100 Subject: [PATCH 48/61] [doc] Update release notes (#4749) --- docs/pages/release_notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 905f044caa..28d3e99fa4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -97,6 +97,7 @@ in the Migration Guide. * [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21 * [#4586](https://github.com/pmd/pmd/pull/4586): Use explicit encoding in ruleset xml files * [#4741](https://github.com/pmd/pmd/pull/4741): Add pmd-compat6 module for maven-pmd-plugin + * [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6 * apex-performance * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop * java-codestyle @@ -132,6 +133,7 @@ The following previously deprecated classes have been removed: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6 - [Andreas Bergander](https://github.com/bergander) (@bergander) ### 🚀 Major Features and Enhancements @@ -479,6 +481,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4691](https://github.com/pmd/pmd/issues/4691): \[CVEs] Critical and High CEVs reported on PMD and PMD dependencies * [#4699](https://github.com/pmd/pmd/pull/4699): Make PMD buildable with java 21 * [#4741](https://github.com/pmd/pmd/pull/4741): Add pmd-compat6 module for maven-pmd-plugin + * [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6 * ant * [#4080](https://github.com/pmd/pmd/issues/4080): \[ant] Split off Ant integration into a new submodule * core @@ -788,6 +791,7 @@ Language specific fixes: * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) +* [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6 - [Andreas Bergander](https://github.com/bergander) (@bergander) ### 📈 Stats * 5007 commits From dbfde44b9259b915982770549f31a28340d62c02 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 09:56:18 +0100 Subject: [PATCH 49/61] [swift] Make Macro expansion an expression Add parser tests --- .../sourceforge/pmd/lang/swift/ast/Swift.g4 | 11 +- .../pmd/lang/swift/ast/SwiftParserTests.java | 9 + .../testdata/MacroExpansionExpressions.swift | 11 + .../testdata/MacroExpansionExpressions.txt | 207 ++++++++++ .../lang/swift/ast/testdata/Swift5.9.swift | 43 ++ .../pmd/lang/swift/ast/testdata/Swift5.9.txt | 386 ++++++++++++++++++ 6 files changed, 662 insertions(+), 5 deletions(-) create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.swift create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.txt create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.swift create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.txt diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 index d997b621fa..7961bb7544 100644 --- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 +++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 @@ -211,7 +211,6 @@ declaration | constantDeclaration ';'? | variableDeclaration ';'? | typealiasDeclaration ';'? - | macroExpansionExpression ';'? | functionDeclaration ';'? | enumDeclaration ';'? | structDeclaration ';'? @@ -298,10 +297,6 @@ typealiasHead : attributes? accessLevelModifier? 'typealias' typealiasName gener typealiasName : identifier ; typealiasAssignment : '=' sType ; -// GRAMMAR OF A MACRO DECLARATION - -macroExpansionExpression: '#' identifier genericArgumentClause? functionCallArgumentClause? ; - // GRAMMAR OF A FUNCTION DECLARATION /* HACK: functionBody? is intentionally not used to force the parser to try and match a functionBody first @@ -601,6 +596,7 @@ primaryExpression | implicitMemberExpression // | implicit_member_expression disallow as ambig with explicit member expr in postfix_expression | wildcardExpression + | macroExpansionExpression | selectorExpression | keyPathExpression ; @@ -690,6 +686,11 @@ tupleElement: (identifier ':')? expression ; wildcardExpression : '_' ; +// GRAMMAR OF A MACRO EXPANSION EXPRESSION +// https://docs.swift.org/swift-book/documentation/the-swift-programming-language/expressions#Macro-Expansion-Expression +// https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion +macroExpansionExpression: '#' identifier genericArgumentClause? functionCallArgumentClause? ; + // GRAMMAR OF A SELECTOR EXPRESSION selectorExpression diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java index 7c4a75b7c7..886fe3e003 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java @@ -18,4 +18,13 @@ class SwiftParserTests extends BaseSwiftTreeDumpTest { doTest("BTree"); } + @Test + void swift59() { + doTest("Swift5.9"); + } + + @Test + void macroExpansions() { + doTest("MacroExpansionExpressions"); + } } diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.swift new file mode 100644 index 0000000000..1c9f901d73 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.swift @@ -0,0 +1,11 @@ +// Samples from https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion + +// macro expansion expression with one argument +let _: (Int, String) = #addBlocker(x + y * z) + +// macro expansion expressions within macro arguments +let _: (Int, String) = #addBlocker(#stringify(1 + 2)) + +// default built-in macros +let _: String = #fileID +let _: Int = #line diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.txt new file mode 100644 index 0000000000..4b957ae532 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/MacroExpansionExpressions.txt @@ -0,0 +1,207 @@ ++- TopLevel + +- Statements + | +- Statement + | | +- Declaration + | | +- ConstantDeclaration + | | +- T-let + | | +- PatternInitializerList + | | +- PatternInitializer + | | +- Pattern + | | | +- WildcardPattern + | | | | +- T-underscore + | | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TupleType + | | | +- T-lparen + | | | +- TupleTypeElementList + | | | | +- TupleTypeElement + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-comma + | | | | +- TupleTypeElement + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rparen + | | +- Initializer + | | +- T-eq + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- MacroExpansionExpression + | | +- T-hash + | | +- Identifier + | | | +- T-Identifier + | | +- FunctionCallArgumentClause + | | +- T-lparen + | | +- FunctionCallArgumentList + | | | +- FunctionCallArgument + | | | +- Expression + | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- BinaryExpression + | | | | +- BinaryOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-OperatorHead + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- BinaryExpression + | | | +- BinaryOperator + | | | | +- Operator + | | | | +- OperatorHead + | | | | +- T-star + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Identifier + | | | +- T-Identifier + | | +- T-rparen + | +- Statement + | | +- Declaration + | | +- ConstantDeclaration + | | +- T-let + | | +- PatternInitializerList + | | +- PatternInitializer + | | +- Pattern + | | | +- WildcardPattern + | | | | +- T-underscore + | | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TupleType + | | | +- T-lparen + | | | +- TupleTypeElementList + | | | | +- TupleTypeElement + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-comma + | | | | +- TupleTypeElement + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rparen + | | +- Initializer + | | +- T-eq + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- MacroExpansionExpression + | | +- T-hash + | | +- Identifier + | | | +- T-Identifier + | | +- FunctionCallArgumentClause + | | +- T-lparen + | | +- FunctionCallArgumentList + | | | +- FunctionCallArgument + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- MacroExpansionExpression + | | | +- T-hash + | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionCallArgumentClause + | | | +- T-lparen + | | | +- FunctionCallArgumentList + | | | | +- FunctionCallArgument + | | | | +- Expression + | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- LiteralExpression + | | | | | +- Literal + | | | | | +- NumericLiteral + | | | | | +- IntegerLiteral + | | | | | +- T-DecimalLiteral + | | | | +- BinaryExpression + | | | | +- BinaryOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-OperatorHead + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- LiteralExpression + | | | | +- Literal + | | | | +- NumericLiteral + | | | | +- IntegerLiteral + | | | | +- T-DecimalLiteral + | | | +- T-rparen + | | +- T-rparen + | +- Statement + | | +- Declaration + | | +- ConstantDeclaration + | | +- T-let + | | +- PatternInitializerList + | | +- PatternInitializer + | | +- Pattern + | | | +- WildcardPattern + | | | | +- T-underscore + | | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- Initializer + | | +- T-eq + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-directive-file + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Identifier + | | +- T-Identifier + | +- Statement + | +- Declaration + | +- ConstantDeclaration + | +- T-let + | +- PatternInitializerList + | +- PatternInitializer + | +- Pattern + | | +- WildcardPattern + | | | +- T-underscore + | | +- TypeAnnotation + | | +- T-colon + | | +- SType + | | +- TypeIdentifier + | | +- TypeName + | | +- Identifier + | | +- T-Identifier + | +- Initializer + | +- T-eq + | +- Expression + | +- PrefixExpression + | +- PostfixExpression + | +- PrimaryExpression + | +- Keyword + | +- T-directive-line + +- EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.swift new file mode 100644 index 0000000000..f0b3c0663e --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.swift @@ -0,0 +1,43 @@ +import SwiftUI + +struct ContentView: View { + var body: some View { + TabBarView() + } +} + +#Preview { + ContentView() +} + +// Macro Expansion: https://github.com/apple/swift-evolution/blob/main/proposals/0382-expression-macros.md#macro-expansion +let _: Font = #fontLiteral(name: "SF Mono", size: 14, weight: .regular) + +// Parameter packs +func all(_ optional: repeat (each Wrapped)?) -> (repeat each Wrapped)? + +func useAll() { + if let (int, double, string, bool) = all(optionalInt, optionalDouble, optionalString, optionalBool) { + print(int, double, string, bool) + } + else { + print("got a nil") + } +} + +// return value on if/else if/else +statusBar.text = if !hasConnection { "Disconnected" } + else if let error = lastError { error.localizedDescription } + else { "Ready" } + +// https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/ +@attached(member) +@attached(conformance) +public macro OptionSet() = #externalMacro(module: "SwiftMacros", type: "OptionSetMacro") + +import SwiftUI + +#Preview { + Text() + .padding() +} diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.txt new file mode 100644 index 0000000000..dad5eaabde --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Swift5.9.txt @@ -0,0 +1,386 @@ ++- TopLevel + +- Statements + | +- Statement + | | +- Declaration + | | +- ImportDeclaration + | | +- T-import + | | +- ImportPath + | | +- ImportPathIdentifier + | | +- Identifier + | | +- T-Identifier + | +- Statement + | | +- Declaration + | | +- StructDeclaration + | | +- T-struct + | | +- StructName + | | | +- Identifier + | | | +- T-Identifier + | | +- TypeInheritanceClause + | | | +- T-colon + | | | +- TypeInheritanceList + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- StructBody + | | +- T-lbrace + | | +- StructMembers + | | | +- StructMember + | | | +- Declaration + | | | +- VariableDeclaration + | | | +- VariableDeclarationHead + | | | | +- T-var + | | | +- VariableName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypeAnnotation + | | | | +- T-colon + | | | | +- SType + | | | | +- T-some + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionCallArgumentClause + | | | | +- T-lparen + | | | | +- T-rparen + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- MacroExpansionExpression + | | | +- T-hash + | | | +- Identifier + | | | +- T-Identifier + | | +- ClosureExpression + | | +- T-lbrace + | | +- Statements + | | | +- Statement + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionCallArgumentClause + | | | +- T-lparen + | | | +- T-rparen + | | +- T-rbrace + | +- Statement + | | +- Declaration + | | +- ConstantDeclaration + | | +- T-let + | | +- PatternInitializerList + | | +- PatternInitializer + | | +- Pattern + | | | +- WildcardPattern + | | | | +- T-underscore + | | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- Initializer + | | +- T-eq + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- MacroExpansionExpression + | | +- T-hash + | | +- Identifier + | | | +- T-Identifier + | | +- FunctionCallArgumentClause + | | +- T-lparen + | | +- FunctionCallArgumentList + | | | +- FunctionCallArgument + | | | | +- FunctionCallIdentifier + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-colon + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- LiteralExpression + | | | | +- Literal + | | | | +- T-SingleStringLiteral + | | | +- T-comma + | | | +- FunctionCallArgument + | | | | +- FunctionCallIdentifier + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-colon + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- LiteralExpression + | | | | +- Literal + | | | | +- NumericLiteral + | | | | +- IntegerLiteral + | | | | +- T-DecimalLiteral + | | | +- T-comma + | | | +- FunctionCallArgument + | | | +- FunctionCallIdentifier + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-colon + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- ImplicitMemberExpression + | | | +- T-dot + | | | +- Identifier + | | | +- T-Identifier + | | +- T-rparen + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-func + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Identifier + | | | +- T-Identifier + | | +- PostfixOperator + | | +- Operator + | | +- OperatorHead + | | +- T-lt + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Identifier + | | +- T-Identifier + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Identifier + | | +- T-Identifier + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Operator + | | +- OperatorHead + | | +- T-gt + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Error + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-underscore + | +- Statement + | +- LabeledStatement + | +- StatementLabel + | | +- LabelName + | | | +- Identifier + | | | +- ContextSensitiveKeyword + | | | +- T-optional + | | +- T-colon + | +- LoopStatement + | +- RepeatWhileStatement + | +- T-repeat + | +- CodeBlock + | | +- Error + | | +- Statements + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Error + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Identifier + | | | +- T-Identifier + | | +- Error + | +- Error + | +- Expression + | +- PrefixExpression + | +- PostfixExpression + | +- PrimaryExpression + | +- Operator + | +- OperatorHead + | +- T-question + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error From 020e2da270056f9550d3ddcfe99241eb3d99cf60 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 09:57:27 +0100 Subject: [PATCH 50/61] [swift] Log parser errors * Eventually, this should throw, but the grammar is very incomplete. * Support opaque-types --- docs/pages/pmd/languages/swift.md | 2 ++ .../net/sourceforge/pmd/lang/swift/ast/Swift.g4 | 4 +++- .../pmd/lang/swift/ast/PmdSwiftParser.java | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/languages/swift.md b/docs/pages/pmd/languages/swift.md index c4d23bcf97..1f93eed49a 100644 --- a/docs/pages/pmd/languages/swift.md +++ b/docs/pages/pmd/languages/swift.md @@ -10,3 +10,5 @@ summary: "Swift-specific features and guidance" > powerful for experts. It is fast, modern, safe, and a joy to write. {% include language_info.html name='Swift' id='swift' implementation='swift::lang.swift.SwiftLanguageModule' supports_pmd=true supports_cpd=true since='5.3.7' %} + +The grammar of the languages is documented in [The Swift Language Reference](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/aboutthelanguagereference/). diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 index 7961bb7544..7c60e80941 100644 --- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 +++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 @@ -837,6 +837,7 @@ sType | sType '?' // optional-type | sType '!' // implicitly-unwrapped-optional-type | protocolCompositionType + | 'some' sType // opaque-type | sType '.' 'Type' | sType '.' 'Protocol' // metatype | 'Any' | 'Self' ; @@ -969,7 +970,8 @@ contextSensitiveKeyword : 'lazy' | 'left' | 'mutating' | 'none' | 'nonmutating' | 'optional' | 'operator' | 'override' | 'postfix' | 'precedence' | 'prefix' | 'Protocol' | 'required' | 'right' | 'set' | 'Type' | 'unowned' | 'weak' | 'willSet' | 'iOS' | 'iOSApplicationExtension' | 'OSX' | 'OSXApplicationExtension­' | 'watchOS' | 'x86_64' | - 'arm' | 'arm64' | 'i386' | 'os' | 'arch' | 'safe' | 'tvOS' | 'file' | 'line' | 'default' | 'Self' | 'var' + 'arm' | 'arm64' | 'i386' | 'os' | 'arch' | 'safe' | 'tvOS' | 'file' | 'line' | 'default' | 'Self' | 'var' | + 'some' ; grammarString: diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java index 2c6abae5db..cf285d772e 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java @@ -4,9 +4,14 @@ package net.sourceforge.pmd.lang.swift.ast; +import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseParser; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwTopLevel; @@ -15,10 +20,21 @@ import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwTopLevel; * Adapter for the SwiftParser. */ public final class PmdSwiftParser extends AntlrBaseParser { + private static final Logger LOGGER = LoggerFactory.getLogger(PmdSwiftParser.class); @Override protected SwTopLevel parse(final Lexer lexer, ParserTask task) { SwiftParser parser = new SwiftParser(new CommonTokenStream(lexer)); + parser.removeErrorListeners(); + parser.addErrorListener(new BaseErrorListener() { + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + LOGGER.warn("Syntax error at {}:{}:{}: {}", task.getFileId().getOriginalPath(), + line, charPositionInLine, msg); + // TODO: eventually we should throw a parse exception + // throw new ParseException(msg).withLocation(FileLocation.caret(task.getFileId(), line, charPositionInLine)); + } + }); return parser.topLevel().makeAstInfo(task); } From 84c2eb7511c94c95c08c78e6e08406196b0a97ac Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 10:04:29 +0100 Subject: [PATCH 51/61] [doc] Update release notes (#4698) --- docs/pages/release_notes.md | 7 +++++++ docs/pages/release_notes_pmd7.md | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 71f4e34bdb..b035e99a63 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -73,6 +73,10 @@ As PMD 7 revamped the Java module, if you have custom rules, you need to migrate See the use case [I'm using custom rules]({{ baseurl }}pmd_userdocs_migrating_to_pmd7.html#im-using-custom-rules) in the Migration Guide. +##### Swift Support + +* limited support for Swift 5.9 (Macro Expansions) + #### Rule Changes **New Rules** @@ -140,6 +144,7 @@ The following previously deprecated classes have been removed: * [#4640](https://github.com/pmd/pmd/pull/4640): \[cli] Launch script fails if run via "bash pmd" - [Shai Bennathan](https://github.com/shai-bennathan) (@shai-bennathan) * [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) +* [#4698](https://github.com/pmd/pmd/pull/4698): \[swift] Add macro expansion support for swift 5.9 - [Richard B.](https://github.com/kenji21) (@kenji21) * [#4706](https://github.com/pmd/pmd/pull/4706): \[java] DetachedTestCase should not report on abstract methods - [Debamoy Datta](https://github.com/Debamoy) (@Debamoy) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) @@ -215,6 +220,7 @@ For more information on the languages, see the [Detailed Release Notes for PMD 7 #### New: Swift support * use PMD to analyze Swift code with PMD rules +* limited support for Swift 5.9 (Macro Expansions) * initially 4 built-in rules Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), @@ -805,6 +811,7 @@ Language specific fixes: * [#4665](https://github.com/pmd/pmd/pull/4665): \[java] Doc: Fix references AutoClosable -> AutoCloseable - [Andrey Bozhko](https://github.com/AndreyBozhko) (@AndreyBozhko) * [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation - [Wener](https://github.com/wener-tiobe) (@wener-tiobe) * [#4677](https://github.com/pmd/pmd/pull/4677): \[apex] Add new rule: OperationWithHighCostInLoop - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) +* [#4698](https://github.com/pmd/pmd/pull/4698): \[swift] Add macro expansion support for swift 5.9 - [Richard B.](https://github.com/kenji21) (@kenji21) * [#4706](https://github.com/pmd/pmd/pull/4706): \[java] DetachedTestCase should not report on abstract methods - [Debamoy Datta](https://github.com/Debamoy) (@Debamoy) * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string - [ciufudean](https://github.com/ciufudean) (@ciufudean) * [#4738](https://github.com/pmd/pmd/pull/4738): \[doc] Added reference to the PMD extension for bld - [Erik C. Thauvin](https://github.com/ethauvin) (@ethauvin) diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 6ec4ba8b3f..6ead880e2d 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -154,8 +154,12 @@ See [the example report](report-examples/cpdhtml-v2.html). ### New: Swift support -Given the full Antlr support, PMD now fully supports Swift. We are pleased to announce we are shipping a number of -rules starting with PMD 7. +Given the full Antlr support, PMD now fully supports Swift for creating rules. Previously only CPD was supported. + +Note: There is only limited support for newer Swift language features in the parser, e.g. Swift 5.9 (Macro Expansions) +are supported, but other features are not. + +We are pleased to announce we are shipping a number of rules starting with PMD 7. * {% rule "swift/errorprone/ForceCast" %} (`swift-errorprone`) flags all force casts, making sure you are defensively considering all types. Having the application crash shouldn't be an option. From dfcde5acdee58acbd13265fe3be6cd61893f2b51 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 10:35:14 +0100 Subject: [PATCH 52/61] [doc] Update release notes (#4697) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7296758498..592bff4003 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -123,6 +123,8 @@ in the Migration Guide. * [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string * javascript * [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation +* swift + * [#4697](https://github.com/pmd/pmd/issues/4697): \[swift] Support Swift 5.9 features (mainly macros expansion expressions) * xml-bestpractices * [#4592](https://github.com/pmd/pmd/pull/4592): \[xml] Add MissingEncoding rule @@ -769,6 +771,7 @@ Language specific fixes: * swift * [#1877](https://github.com/pmd/pmd/pull/1877): \[swift] Feature/swift rules * [#1882](https://github.com/pmd/pmd/pull/1882): \[swift] UnavailableFunction Swift rule + * [#4697](https://github.com/pmd/pmd/issues/4697): \[swift] Support Swift 5.9 features (mainly macros expansion expressions) * xml * [#1800](https://github.com/pmd/pmd/pull/1800): \[xml] Unimplement org.w3c.dom.Node from the XmlNodeWrapper * xml-bestpractices From 9ecbe2e5ce86afbc78f05be8f7da212f40bffb7a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 10:49:44 +0100 Subject: [PATCH 53/61] [cli] Use setters for --dir and positional parameters This makes it possible to combine both inputs into a single list of files to be analyzed. --- .../AbstractAnalysisPmdSubcommand.java | 50 ++++++++++--------- .../commands/internal/BaseCommandTest.java | 3 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 490c2b9af0..6fe95a4517 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd.cli.commands.internal; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import net.sourceforge.pmd.AbstractConfiguration; @@ -24,23 +25,11 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths; - @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " - + "Equivalent to using --dir.") - // Note: we can't directly use inputPaths here, because "--dir" might be specified later in the - // command line. And PicoCli will then initialize the field inputPaths with a fresh empty List, replacing - // anything what was added before.So we need to combine the two lists in #validate() - private List positionalInputPaths; - - @Option(names = "--file-list", description = "Path to a file containing a list of files to analyze, one path per line. " @@ -66,7 +55,7 @@ public abstract class AbstractAnalysisPmdSubcommand rootPaths) { + protected void setRelativizePathsWith(List rootPaths) { this.relativizeRootPaths = rootPaths; for (Path path : this.relativizeRootPaths) { @@ -77,18 +66,31 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths) { + if (this.inputPaths == null) { + this.inputPaths = new ArrayList<>(); + } + + this.inputPaths.addAll(inputPaths); + } + + @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " + + "Equivalent to using --dir.") + protected void setPositionalInputPaths(final List inputPaths) { + this.setInputPaths(inputPaths); + } + @Override protected final void validate() throws ParameterException { super.validate(); - if (positionalInputPaths != null) { - if (inputPaths == null) { - inputPaths = positionalInputPaths; - } else { - inputPaths.addAll(positionalInputPaths); - } - } - if ((inputPaths == null || inputPaths.isEmpty()) && uri == null && fileListPath == null) { throw new ParameterException(spec.commandLine(), "Please provide a parameter for source root directory (--dir or -d), " diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java index f2388d4076..6057a549b9 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java @@ -15,7 +15,7 @@ import org.hamcrest.Matchers; import picocli.CommandLine; import picocli.CommandLine.ParseResult; -abstract class BaseCommandTest> { +abstract class BaseCommandTest { protected abstract T createCommand(); @@ -30,7 +30,6 @@ abstract class BaseCommandTest> { protected T setupAndParse(final String... params) { final T cmd = createCommand(); final ParseResult parseResult = parseCommand(cmd, params); - cmd.validate(); assertThat(parseResult.errors(), Matchers.empty()); From 1ecda3f74986bae3d104c942a22544a999a3e092 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 10:52:44 +0100 Subject: [PATCH 54/61] [doc] Update release notes (#4685) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 373c31e11f..f013fbc2e5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -95,6 +95,7 @@ in the Migration Guide. * cli * [#4594](https://github.com/pmd/pmd/pull/4594): \[cli] Change completion generation to runtime + * [#4685](https://github.com/pmd/pmd/pull/4685): \[cli] Clarify CPD documentation, fix positional parameter handling * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" * core * [#1027](https://github.com/pmd/pmd/issues/1027): \[core] Apply the new PropertyDescriptor<Pattern> type where applicable @@ -561,6 +562,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE * [#4594](https://github.com/pmd/pmd/pull/4594): \[cli] Change completion generation to runtime + * [#4685](https://github.com/pmd/pmd/pull/4685): \[cli] Clarify CPD documentation, fix positional parameter handling * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" * doc * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation From 6ea7206f65e9da39965c100e0033cdad7c463d92 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 11:14:16 +0100 Subject: [PATCH 55/61] Fix unit tests --- .../commands/internal/AbstractAnalysisPmdSubcommand.java | 7 ++++--- .../sourceforge/pmd/cli/commands/internal/CpdCommand.java | 2 +- .../sourceforge/pmd/cli/commands/internal/PmdCommand.java | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 6fe95a4517..e45086a60a 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -7,8 +7,9 @@ package net.sourceforge.pmd.cli.commands.internal; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import net.sourceforge.pmd.AbstractConfiguration; import net.sourceforge.pmd.cli.commands.mixins.internal.EncodingMixin; @@ -28,7 +29,7 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths; + protected Set inputPaths; @Option(names = "--file-list", description = @@ -75,7 +76,7 @@ public abstract class AbstractAnalysisPmdSubcommand inputPaths) { if (this.inputPaths == null) { - this.inputPaths = new ArrayList<>(); + this.inputPaths = new LinkedHashSet<>(); // linked hashSet in order to maintain order } this.inputPaths.addAll(inputPaths); diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index 1b61689251..2e71305cef 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -105,7 +105,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand configuration.setFailOnViolation(failOnViolation); configuration.setInputFilePath(fileListPath); if (inputPaths != null) { - configuration.setInputPathList(inputPaths); + configuration.setInputPathList(new ArrayList<>(inputPaths)); } configuration.setIgnoreAnnotations(ignoreAnnotations); configuration.setIgnoreIdentifiers(ignoreIdentifiers); diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index ae2956238f..a4c7e016dd 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -260,7 +260,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand protected PMDConfiguration toConfiguration() { final PMDConfiguration configuration = new PMDConfiguration(); if (inputPaths != null) { - configuration.setInputPathList(inputPaths); + configuration.setInputPathList(new ArrayList<>(inputPaths)); } configuration.setInputFilePath(fileListPath); configuration.setIgnoreFilePath(ignoreListPath); From 552ce7d36ff95ea16a9973a43f393fca349b59b9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 11 Dec 2023 13:42:01 +0100 Subject: [PATCH 56/61] [doc] Update release notes and docs for groovy (#4726) --- docs/pages/pmd/languages/groovy.md | 8 ++++++++ docs/pages/pmd/userdocs/cpd/cpd.md | 2 +- docs/pages/release_notes.md | 18 ++++++++++++++++++ docs/pages/release_notes_pmd7.md | 6 ++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/languages/groovy.md b/docs/pages/pmd/languages/groovy.md index 25ea52b751..6b9e4c62fe 100644 --- a/docs/pages/pmd/languages/groovy.md +++ b/docs/pages/pmd/languages/groovy.md @@ -11,3 +11,11 @@ summary: "Groovy-specific features and guidance" > familiar and easy to learn syntax. {% include language_info.html name='Groovy' id='groovy' implementation='groovy::lang.groovy.GroovyLanguageModule' supports_cpd=true since='5.5.2' %} + +## Support in PMD +Groovy support was added with PMD 5.5.2. With PMD 7.0.0, support for Groovy 3 and 4 was added. + +Since PMD 7.0.0, the Groovy module supports [suppression](pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. + +### Limitations +- Support for Groovy only extends to CPD to detect code duplication. diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 1775fa0840..46ba4f6110 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -477,7 +477,7 @@ Here's a screenshot of CPD after running on the JDK 8 java.lang package: ## Suppression -Arbitrary blocks of code can be ignored through comments on **Java**, **C/C++**, **Dart**, **Go**, **Javascript**, +Arbitrary blocks of code can be ignored through comments on **Java**, **C/C++**, **Dart**, **Go**, **Groovy**, **Javascript**, **Kotlin**, **Lua**, **Matlab**, **Objective-C**, **PL/SQL**, **Python**, **Scala**, **Swift** and **C#** by including the keywords `CPD-OFF` and `CPD-ON`. ```java diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7f414fb148..11da4a32ba 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -77,6 +77,12 @@ in the Migration Guide. * limited support for Swift 5.9 (Macro Expansions) +##### Groovy Support (CPD) + +* We now support parsing all Groovy features from Groovy 3 and 4. +* We now support [suppression](pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. +* See [PR #4726](https://github.com/pmd/pmd/pull/4726) for details. + #### Rule Changes **New Rules** @@ -99,6 +105,7 @@ in the Migration Guide. * [#4723](https://github.com/pmd/pmd/issues/4723): \[cli] Launch fails for "bash pmd" * core * [#1027](https://github.com/pmd/pmd/issues/1027): \[core] Apply the new PropertyDescriptor<Pattern> type where applicable + * [#4674](https://github.com/pmd/pmd/issues/4674): \[core] WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * doc * [#3175](https://github.com/pmd/pmd/issues/3175): \[doc] Document language module features @@ -113,6 +120,8 @@ in the Migration Guide. * [#4749](https://github.com/pmd/pmd/pull/4749): Fixes NoSuchMethodError on processing errors in pmd-compat6 * apex-performance * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop +* groovy + * [#4726](https://github.com/pmd/pmd/pull/4726): \[groovy] Support Groovy to 3 and 4 and CPD suppressions * java * [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards * java-codestyle @@ -309,6 +318,12 @@ Note: Support for Java 19 preview language features have been removed. The versi With the new version of Apex Jorje, the new language constructs like User Mode Database Operations can be parsed now. PMD should now be able to parse Apex code up to version 59.0 (Winter '23). +#### Changed: Groovy Support (CPD) + +* We now support parsing all Groovy features from Groovy 3 and 4. +* We now support [suppression](pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. +* See [PR #4726](https://github.com/pmd/pmd/pull/4726) for details. + #### Changed: Rule properties * The old deprecated classes like `IntProperty` and `StringProperty` have been removed. Please use @@ -555,6 +570,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4454](https://github.com/pmd/pmd/issues/4454): \[core] "Unknown option: '-min'" but is referenced in documentation * [#4611](https://github.com/pmd/pmd/pull/4611): \[core] Fix loading language properties from env vars * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first + * [#4674](https://github.com/pmd/pmd/issues/4674): \[core] WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * cli * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command @@ -598,6 +614,8 @@ Language specific fixes: * [#4675](https://github.com/pmd/pmd/issues/4675): \[apex] New Rule: OperationWithHighCostInLoop * apex-security * [#4646](https://github.com/pmd/pmd/issues/4646): \[apex] ApexSOQLInjection does not recognise SObjectType or SObjectField as safe variable types +* groovy + * [#4726](https://github.com/pmd/pmd/pull/4726): \[groovy] Support Groovy to 3 and 4 and CPD suppressions * java * [#520](https://github.com/pmd/pmd/issues/520): \[java] Allow `@SuppressWarnings` with constants instead of literals * [#864](https://github.com/pmd/pmd/issues/864): \[java] Similar/duplicated implementations for determining FQCN diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index f9e59e325e..65dafb1eca 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -279,6 +279,12 @@ Related issue: [[core] Explicitly name all language versions (#4120)](https://gi With the new version of Apex Jorje, the new language constructs like User Mode Database Operations can be parsed now. PMD should now be able to parse Apex code up to version 59.0 (Winter '23). +### Changed: Groovy Support (CPD) + +* We now support parsing all Groovy features from Groovy 3 and 4. +* We now support [suppression](pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. +* See [PR #4726](https://github.com/pmd/pmd/pull/4726) for details. + ## 🌟 New and changed rules ### New Rules From a558fd17eb6d8f75a7e5f80c83249d96d0b11043 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 16 Dec 2023 13:03:32 +0100 Subject: [PATCH 57/61] [ci] Use bundler 2.4.22, which is still compatible with ruby 2.7 --- .ci/build.sh | 2 +- Gemfile.lock | 16 ++++++++-------- docs/Gemfile.lock | 32 +++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index e2b73e677a..9927f9e5ee 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -169,7 +169,7 @@ function build() { # function pmd_ci_build_setup_bundler() { pmd_ci_log_info "Installing bundler..." - gem install bundler + gem install bundler -v 2.4.22 } # diff --git a/Gemfile.lock b/Gemfile.lock index 8eca47b101..0b428aa00e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) base64 (0.2.0) claide (1.1.0) @@ -13,7 +13,7 @@ GEM concurrent-ruby (1.2.2) cork (0.3.0) colored2 (~> 3.1) - danger (9.4.0) + danger (9.4.2) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -24,12 +24,12 @@ GEM kramdown (~> 2.3) kramdown-parser-gfm (~> 1.0) no_proxy_fix - octokit (>= 6.0, < 8.0) + octokit (>= 4.0) terminal-table (>= 1, < 4) differ (0.1.2) et-orbi (1.2.7) tzinfo - faraday (2.7.11) + faraday (2.7.12) base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) @@ -51,10 +51,10 @@ GEM mini_portile2 (2.8.5) nap (1.1.0) no_proxy_fix (0.1.2) - nokogiri (1.15.4) + nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) - octokit (7.2.0) + octokit (8.0.0) faraday (>= 1, < 3) sawyer (~> 0.9) open4 (1.3.4) @@ -65,7 +65,7 @@ GEM nokogiri (~> 1.13) rufus-scheduler (~> 3.8) slop (~> 4.9) - public_suffix (5.0.3) + public_suffix (5.0.4) raabro (1.4.0) racc (1.7.3) rchardet (1.8.0) @@ -96,4 +96,4 @@ DEPENDENCIES safe_yaml BUNDLED WITH - 2.4.5 + 2.4.22 diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 127620dcb2..d12c952e1b 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,14 +1,20 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.0.8) + activesupport (7.1.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - base64 (0.1.1) + base64 (0.2.0) + bigdecimal (3.1.5) coffee-script (2.4.1) coffee-script-source execjs @@ -16,8 +22,11 @@ GEM colorator (1.1.0) commonmarker (0.23.10) concurrent-ruby (1.2.2) + connection_pool (2.4.1) dnsruby (1.70.0) simpleidn (~> 0.2.1) + drb (2.2.0) + ruby2_keywords em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -25,12 +34,12 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.9.1) - faraday (2.7.11) + faraday (2.7.12) base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) - ffi (1.16.2) + ffi (1.16.3) forwardable-extended (2.6.0) gemoji (3.0.1) github-pages (228) @@ -207,13 +216,14 @@ GEM rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) - mini_portile2 (2.8.4) + mini_portile2 (2.8.5) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.20.0) - nokogiri (1.15.4) + mutex_m (0.2.0) + nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) octokit (4.25.1) @@ -222,7 +232,7 @@ GEM pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (4.0.7) - racc (1.7.1) + racc (1.7.3) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) @@ -243,13 +253,13 @@ GEM unf (~> 0.1.4) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - typhoeus (1.4.0) + typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unf (0.1.4) unf_ext - unf_ext (0.0.8.2) + unf_ext (0.0.9.1) unicode-display_width (1.8.0) webrick (1.8.1) @@ -262,4 +272,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.4.5 + 2.4.22 From b65589175cb69dd59df202a173efbe76d175797e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Jan 2024 14:48:10 +0100 Subject: [PATCH 58/61] [core] Add tests for TokenMgrError location --- .../pmd/lang/ast/TokenMgrError.java | 2 +- .../pmd/lang/ast/TokenMgrErrorTest.java | 37 +++++++++++++++++++ .../pmd/lang/java/cpd/JavaTokenizerTest.java | 23 ++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/TokenMgrErrorTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java index 3b6366fb45..28bee8a79e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/TokenMgrError.java @@ -27,7 +27,7 @@ public final class TokenMgrError extends FileAnalysisException { * * @param line Line number * @param column Column number - * @param filename Filename. If unknown, it can be completed with {@link #setFileName(String)} later + * @param filename Filename. If unknown, it can be completed with {@link #setFileId(FileId)}} later * @param message Message of the error * @param cause Cause of the error, if any */ diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/TokenMgrErrorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/TokenMgrErrorTest.java new file mode 100644 index 0000000000..806d5e743e --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/TokenMgrErrorTest.java @@ -0,0 +1,37 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class TokenMgrErrorTest { + @Test + void invalidLocation() { + TokenMgrError error = new TokenMgrError(2, 0, null, "test", null); + // this shouldn't throw a IllegalArgumentException + assertEquals("line 2, column 1", error.location().startPosToString()); + } + + @Test + void invalidLocationJavaCC() { + TokenMgrError error = new TokenMgrError(false, "DEFAULT", 2, 0, "}", '\n'); + // this shouldn't throw a IllegalArgumentException + assertEquals("line 2, column 1", error.location().startPosToString()); + } + + @Test + void validLocation() { + TokenMgrError error = new TokenMgrError(1, 1, null, "test", null); + assertEquals("line 1, column 1", error.location().startPosToString()); + } + + @Test + void validLocationJavaCC() { + TokenMgrError error = new TokenMgrError(false, "DEFAULT", 1, 1, "}", '\n'); + assertEquals("line 1, column 1", error.location().startPosToString()); + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/cpd/JavaTokenizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/cpd/JavaTokenizerTest.java index 67e211f13c..17a873fc1c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/cpd/JavaTokenizerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/cpd/JavaTokenizerTest.java @@ -4,12 +4,21 @@ package net.sourceforge.pmd.lang.java.cpd; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertThrows; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import net.sourceforge.pmd.cpd.CpdLanguageProperties; +import net.sourceforge.pmd.cpd.Tokenizer; +import net.sourceforge.pmd.cpd.Tokens; import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; import net.sourceforge.pmd.cpd.test.LanguagePropertyConfig; +import net.sourceforge.pmd.lang.ast.TokenMgrError; +import net.sourceforge.pmd.lang.document.FileId; +import net.sourceforge.pmd.lang.document.TextDocument; import net.sourceforge.pmd.lang.java.JavaLanguageModule; // TODO - enable tests @@ -29,6 +38,20 @@ class JavaTokenizerTest extends CpdTextComparisonTest { doTest("StringTemplateReduction"); } + @Test + void testLexExceptionLocation() { + Tokenizer tokenizer = newTokenizer(defaultProperties()); + Tokens tokens = new Tokens(); + TokenMgrError lexException = assertThrows(TokenMgrError.class, () -> + Tokenizer.tokenize(tokenizer, + // note: the source deliberately contains an unbalanced quote, unterminated string literal + TextDocument.readOnlyString("class F {\n String s=\"abc\";\"\n}\n", FileId.UNKNOWN, getLanguage().getDefaultVersion()), + tokens) + ); + // this shouldn't throw a IllegalArgumentException + assertThat(lexException.getMessage(), containsString("at line 3, column 1")); + } + @Test void testStringTemplateReduction2() { doTest("StringTemplateReduction2"); From fb0e9c53445298af68eaca8fde5b730a1e1aa6ac Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Jan 2024 14:50:06 +0100 Subject: [PATCH 59/61] [doc] Update release notes (#4694) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0f2c592ae6..2249b3fff9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -106,6 +106,7 @@ in the Migration Guide. * core * [#1027](https://github.com/pmd/pmd/issues/1027): \[core] Apply the new PropertyDescriptor<Pattern> type where applicable * [#4674](https://github.com/pmd/pmd/issues/4674): \[core] WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass + * [#4694](https://github.com/pmd/pmd/pull/4694): \[core] Fix line/col numbers in TokenMgrError * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * doc * [#3175](https://github.com/pmd/pmd/issues/3175): \[doc] Document language module features @@ -572,6 +573,7 @@ See also [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7. * [#4611](https://github.com/pmd/pmd/pull/4611): \[core] Fix loading language properties from env vars * [#4621](https://github.com/pmd/pmd/issues/4621): \[core] Make `ClasspathClassLoader::getResource` child first * [#4674](https://github.com/pmd/pmd/issues/4674): \[core] WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass + * [#4694](https://github.com/pmd/pmd/pull/4694): \[core] Fix line/col numbers in TokenMgrError * [#4750](https://github.com/pmd/pmd/pull/4750): \[core] Fix flaky SummaryHTMLRenderer * cli * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command From 194a644cee9799bfe4113f920f568140b80ded8e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Jan 2024 14:57:09 +0100 Subject: [PATCH 60/61] [ci] Bump build-tools to 23-SNAPSHOT Should fix the expired release key --- .github/workflows/build.yml | 2 +- .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/troubleshooting.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5deaf0faa4..f13e39168d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/22/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index cce1368735..bce9f91e55 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -24,7 +24,7 @@ jobs: shell: bash run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/22/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV - name: Sync run: .ci/git-repo-sync.sh shell: bash diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml index c39674aad2..ecfd6e785c 100644 --- a/.github/workflows/troubleshooting.yml +++ b/.github/workflows/troubleshooting.yml @@ -36,7 +36,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/22/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | From bd7fb70c1300d7390c710814d6995568e5d938ea Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Jan 2024 14:59:39 +0100 Subject: [PATCH 61/61] [ci] Bump build-tools to master (23-SNAPSHOT) Should fix the expired release key --- .github/workflows/build.yml | 2 +- .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/troubleshooting.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f13e39168d..bd09abe501 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index bce9f91e55..c564eeea92 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -24,7 +24,7 @@ jobs: shell: bash run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV - name: Sync run: .ci/git-repo-sync.sh shell: bash diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml index ecfd6e785c..70006cb241 100644 --- a/.github/workflows/troubleshooting.yml +++ b/.github/workflows/troubleshooting.yml @@ -36,7 +36,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/23-SNAPSHOT/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: |