[compat6] Support other cpd languages like cs
This commit is contained in:
2
pmd-compat6/src/it/cpd-for-csharp/invoker.properties
Normal file
2
pmd-compat6/src/it/cpd-for-csharp/invoker.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
invoker.goals = verify
|
||||
invoker.buildResult = failure
|
||||
78
pmd-compat6/src/it/cpd-for-csharp/pom.xml
Normal file
78
pmd-compat6/src/it/cpd-for-csharp/pom.xml
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.sourceforge.pmd.pmd-compat6.it</groupId>
|
||||
<artifactId>cpd-for-csharp</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>@maven-pmd-plugin.version.for.integrationtest@</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>csharp-cpd-check</id>
|
||||
<goals>
|
||||
<goal>cpd-check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<language>cs</language>
|
||||
<minimumTokens>10</minimumTokens>
|
||||
<includes>
|
||||
<include>**/*.cs</include>
|
||||
</includes>
|
||||
<compileSourceRoots>
|
||||
<compileSourceRoot>${basedir}/src/main/cs</compileSourceRoot>
|
||||
</compileSourceRoots>
|
||||
<printFailingErrors>true</printFailingErrors>
|
||||
<skipPmdError>false</skipPmdError>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-compat6</artifactId>
|
||||
<version>@project.version@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-core</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-java</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-javascript</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-jsp</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-cs</artifactId>
|
||||
<version>@pmd.version.for.integrationtest@</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs
Normal file
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings1.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
class Foo {
|
||||
void bar() {
|
||||
|
||||
var test = $@"test";
|
||||
var test2 = @$"test";
|
||||
|
||||
String query =
|
||||
@"SELECT foo, bar
|
||||
FROM table
|
||||
WHERE id = 42";
|
||||
}
|
||||
}
|
||||
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs
Normal file
12
pmd-compat6/src/it/cpd-for-csharp/src/main/cs/strings2.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
class Foo {
|
||||
void bar() {
|
||||
|
||||
var test = $@"test";
|
||||
var test2 = @$"test";
|
||||
|
||||
String query =
|
||||
@"SELECT foo, bar
|
||||
FROM table
|
||||
WHERE id = 42";
|
||||
}
|
||||
}
|
||||
46
pmd-compat6/src/it/cpd-for-csharp/verify.bsh
Normal file
46
pmd-compat6/src/it/cpd-for-csharp/verify.bsh
Normal file
@@ -0,0 +1,46 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
||||
String readFile(File file) throws IOException {
|
||||
StringBuilder content = new StringBuilder();
|
||||
for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) {
|
||||
content.append(line).append(System.lineSeparator());
|
||||
}
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
File buildLogPath = new File(basedir, "build.log");
|
||||
String buildLog = readFile(buildLogPath);
|
||||
if (buildLog.contains("An API incompatibility was encountered while")) {
|
||||
throw new RuntimeException("Executing failed due to API incompatibility");
|
||||
}
|
||||
|
||||
if (!buildLog.contains("[INFO] CPD Failure: Found 12 lines of duplicated code at locations:")) {
|
||||
throw new RuntimeException("No CPD failures detected, did CPD run?");
|
||||
}
|
||||
File classA = new File("cpd-for-csharp/src/main/cs/strings1.cs");
|
||||
if (!buildLog.contains(classA + " line 1")) {
|
||||
throw new RuntimeException("No CPD failures detected, did CPD run?");
|
||||
}
|
||||
File classB = new File("cpd-for-csharp/src/main/cs/strings2.cs");
|
||||
if (!buildLog.contains(classA + " line 1")) {
|
||||
throw new RuntimeException("No CPD failures detected, did CPD run?");
|
||||
}
|
||||
|
||||
File cpdXmlReport = new File(basedir, "target/cpd.xml");
|
||||
if (!cpdXmlReport.exists()) {
|
||||
throw new FileNotFoundException("Could not find cpd xml report: " + cpdXmlReport);
|
||||
}
|
||||
String cpdXml = readFile(cpdXmlReport);
|
||||
if (!cpdXml.contains("<duplication lines=\"12\" tokens=\"29\">")) {
|
||||
throw new RuntimeException("Expected duplication has not been reported");
|
||||
}
|
||||
if (!cpdXml.contains(classA + "\"/>")) {
|
||||
throw new RuntimeException("Expected duplication has not been reported");
|
||||
}
|
||||
if (!cpdXml.contains(classB + "\"/>")) {
|
||||
throw new RuntimeException("Expected duplication has not been reported");
|
||||
}
|
||||
@@ -295,6 +295,9 @@ public class CPDConfiguration extends AbstractConfiguration {
|
||||
} else if (language instanceof JSPLanguage) {
|
||||
filenameFilter = language.getFileFilter();
|
||||
setForceLanguageVersion(JspLanguageModule.getInstance().getDefaultVersion());
|
||||
} else if (language instanceof LanguageFactory.CpdLanguageAdapter) {
|
||||
filenameFilter = language.getFileFilter();
|
||||
setForceLanguageVersion(((LanguageFactory.CpdLanguageAdapter) language).getLanguage().getDefaultVersion());
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Language " + language.getName() + " is not supported");
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.sourceforge.pmd.lang.LanguagePropertyBundle;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.properties.PropertyDescriptor;
|
||||
|
||||
public final class LanguageFactory {
|
||||
private LanguageFactory() {
|
||||
@@ -17,6 +22,44 @@ public final class LanguageFactory {
|
||||
}
|
||||
|
||||
public static Language createLanguage(String name, Properties properties) {
|
||||
throw new UnsupportedOperationException();
|
||||
CpdCapableLanguage cpdLanguage = (CpdCapableLanguage) LanguageRegistry.CPD.getLanguageById(name);
|
||||
if (cpdLanguage != null) {
|
||||
return new CpdLanguageAdapter(cpdLanguage, properties);
|
||||
}
|
||||
throw new UnsupportedOperationException("Language " + name + " is not supported");
|
||||
}
|
||||
|
||||
public static class CpdLanguageAdapter extends AbstractLanguage {
|
||||
private CpdCapableLanguage language;
|
||||
|
||||
public CpdLanguageAdapter(CpdCapableLanguage cpdCapableLanguage, Properties properties) {
|
||||
super(cpdCapableLanguage.getName(), cpdCapableLanguage.getId(), createLexer(cpdCapableLanguage, properties), convertExtensions(cpdCapableLanguage));
|
||||
this.language = cpdCapableLanguage;
|
||||
}
|
||||
|
||||
private static Tokenizer createLexer(CpdCapableLanguage cpdCapableLanguage, Properties properties) {
|
||||
LanguagePropertyBundle propertyBundle = cpdCapableLanguage.newPropertyBundle();
|
||||
for (String propName : properties.stringPropertyNames()) {
|
||||
PropertyDescriptor<?> propertyDescriptor = propertyBundle.getPropertyDescriptor(propName);
|
||||
if (propertyDescriptor != null) {
|
||||
setProperty(propertyBundle, propertyDescriptor, properties.getProperty(propName));
|
||||
}
|
||||
}
|
||||
CpdLexer cpdLexer = cpdCapableLanguage.createCpdLexer(propertyBundle);
|
||||
return cpdLexer::tokenize;
|
||||
}
|
||||
|
||||
private static <T> void setProperty(LanguagePropertyBundle propertyBundle, PropertyDescriptor<T> propertyDescriptor, String stringValue) {
|
||||
T value = propertyDescriptor.serializer().fromString(stringValue);
|
||||
propertyBundle.setProperty(propertyDescriptor, value);
|
||||
}
|
||||
|
||||
private static String[] convertExtensions(CpdCapableLanguage cpdCapableLanguage) {
|
||||
return cpdCapableLanguage.getExtensions().stream().map(s -> "." + s).collect(Collectors.toList()).toArray(new String[0]);
|
||||
}
|
||||
|
||||
public CpdCapableLanguage getLanguage() {
|
||||
return language;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user