[core] Remove deprecated methods in Language, LanguageRegistry

Language#getTerseName
LanguageModuleBase#getTerseName
LanguageRegistry#getLanguage
LanguageRegistry#findLanguageByTerseName
LanguageRegistry#findByExtension
This commit is contained in:
Andreas Dangel 2024-02-08 09:12:46 +01:00
parent 90ab50ca29
commit 9e5115479d
No known key found for this signature in database
GPG Key ID: 93450DF2DF9A3FA3
15 changed files with 298 additions and 102 deletions

View File

@ -217,6 +217,16 @@ The following previously deprecated rules have been finally removed:
* `hasOverriddenProperty(PropertyDescriptor)` - use {%jdoc core::lang.rule.RuleReference#isPropertyOverridden(core::properties.PropertyDescriptor) %} instead.
* {%jdoc !!core::lang.rule.XPathRule %}
* The constant `XPATH_DESCRIPTOR` has been made private and is not accessible anymore.
* {%jdoc !!core::lang.Language %} - method `getTerseName()` removed. Use {%jdoc core::lang.Language#getId() %} instead.
* {%jdoc !!core::lang.LanguageModuleBase %} - method `getTerseName()` removed. Use {%jdoc core::lang.LanguageModuleBase#getId() %} instead.
* {%jdoc !!core::lang.LanguageRegistry %} - the following methods have been removed:
* `getLanguage(String)` - use {%jdoc core::lang.LanguageRegistry.getLanguageByFullName(java.lang.String) %}
via {%jdoc core::lang.LanguageRegistry#PMD %} or {%jdoc core::lang.LanguageRegistry#CPD %} instead.
* `findLanguageByTerseName(String)` - use {%jdoc core::lang.LanguageRegistry#getLanguageById(java.lang.String) %}
via {%jdoc core::lang.LanguageRegistry#PMD %} or {%jdoc core::lang.LanguageRegistry#CPD %} instead.
* `findByExtension(String)` - removed without replacement.
* {%jdoc !!core::lang.LanguageVersionDiscoverer %} - method `getLanguagesForFile(java.io.File)` removed.
Use {%jdoc core::lang.LanguageVersionDiscoverer#getLanguagesForFile(java.lang.String) %} instead.
* pmd-apex
* {%jdoc apex::lang.apex.ast.ApexNode %} and {% jdoc apex::lang.apex.ast.ASTApexFile %}
* `#getApexVersion()`: In PMD 6, this method has been deprecated but was defined in the class `ApexRootNode`.

View File

@ -0,0 +1,272 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
// This class has been taken from 7.0.0-SNAPSHOT
// Changes: The following methods are still here, but deleted in 7.0.0
// LanguageRegistry#getLanguage
// LanguageRegistry#findLanguageByTerseName
// LanguageRegistry#findByExtension
package net.sourceforge.pmd.lang;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
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.annotation.DeprecatedUntil700;
import net.sourceforge.pmd.cpd.CpdCapableLanguage;
import net.sourceforge.pmd.util.CollectionUtil;
/**
* A set of languages with convenient methods. In the PMD CLI, languages
* are loaded from the classloader of this class. These are in the registry
* {@link #PMD}. You can otherwise create different registries with different
* languages, eg filter some out.
*/
public final class LanguageRegistry implements Iterable<Language> {
private static final Logger LOG = LoggerFactory.getLogger(LanguageRegistry.class);
private static final LanguageRegistry ALL_LANGUAGES =
loadLanguages(LanguageRegistry.class.getClassLoader());
/**
* Contains the languages that support PMD and are found on the classpath
* of the classloader of this class. This can be used as a "default" registry.
*/
public static final LanguageRegistry PMD = ALL_LANGUAGES.filter(it -> it instanceof PmdCapableLanguage);
/**
* Contains the languages that support CPD and are found on the classpath
* of the classloader of this class.
*/
public static final LanguageRegistry CPD = ALL_LANGUAGES.filter(it -> it instanceof CpdCapableLanguage);
private final Set<Language> languages;
private final Map<String, Language> languagesById;
private final Map<String, Language> languagesByFullName;
/**
* Create a new registry that contains the given set of languages.
* @throws NullPointerException If the parameter is null
*/
public LanguageRegistry(Set<? extends Language> languages) {
this.languages = languages.stream()
.sorted(Comparator.comparing(Language::getId, String::compareToIgnoreCase))
.collect(CollectionUtil.toUnmodifiableSet());
this.languagesById = CollectionUtil.associateBy(languages, Language::getId);
this.languagesByFullName = CollectionUtil.associateBy(languages, Language::getName);
}
/**
* Create a new registry with the languages that satisfy the predicate.
*/
public LanguageRegistry filter(Predicate<Language> filterFun) {
return new LanguageRegistry(languages.stream().filter(filterFun)
.collect(Collectors.toSet()));
}
/**
* Creates a language registry containing a single language. Note
* that this may be inconvertible to a {@link LanguageProcessorRegistry}
* if the language depends on other languages.
*/
public static LanguageRegistry singleton(Language l) {
return new LanguageRegistry(Collections.singleton(l));
}
/**
* Creates a language registry containing the given language and
* its dependencies, fetched from this language registry or the
* parameter.
*
* @throws IllegalStateException If dependencies cannot be fulfilled.
*/
public LanguageRegistry getDependenciesOf(Language lang) {
Set<Language> result = new HashSet<>();
result.add(lang);
addDepsOrThrow(lang, result);
return new LanguageRegistry(result);
}
private void addDepsOrThrow(Language l, Set<Language> languages) {
for (String depId : l.getDependencies()) {
Language dep = getLanguageById(depId);
if (dep == null) {
throw new IllegalStateException(
"Cannot find language " + depId + " in " + this);
}
if (languages.add(dep)) {
addDepsOrThrow(dep, languages);
}
}
}
@Override
public @NonNull Iterator<Language> iterator() {
return languages.iterator();
}
/**
* Create a new registry by loading the languages registered via {@link ServiceLoader}
* on the classpath of the given classloader.
*
* @param classLoader A classloader
*/
public static @NonNull LanguageRegistry loadLanguages(ClassLoader classLoader) {
// sort languages by terse name. Avoiding differences in the order of languages
// across JVM versions / OS.
Set<Language> languages = new TreeSet<>(Comparator.comparing(Language::getId, String::compareToIgnoreCase));
ServiceLoader<Language> languageLoader = ServiceLoader.load(Language.class, classLoader);
Iterator<Language> iterator = languageLoader.iterator();
while (true) {
// this loop is weird, but both hasNext and next may throw ServiceConfigurationError,
// it's more robust that way
try {
if (iterator.hasNext()) {
Language language = iterator.next();
languages.add(language);
} else {
break;
}
} catch (UnsupportedClassVersionError | ServiceConfigurationError e) {
// Some languages require java8 and are therefore only available
// if java8 or later is used as runtime.
LOG.warn("Cannot load PMD language, ignored", e);
}
}
return new LanguageRegistry(languages);
}
/**
* Returns a set of all the known languages. The ordering of the languages
* is by terse name.
*/
public Set<Language> getLanguages() {
return languages;
}
/**
* Returns a language from its {@linkplain Language#getName() full name}
* (eg {@code "Java"}). This is case sensitive.
*
* @param languageName Language name
*
* @return A language, or null if the name is unknown
*
* @deprecated Use {@link #getLanguageByFullName(String) LanguageRegistry.PMD.getLanguageByFullName}
*/
@Deprecated
@DeprecatedUntil700
public static Language getLanguage(String languageName) {
return PMD.getLanguageByFullName(languageName);
}
/**
* Returns a language from its {@linkplain Language#getId() ID}
* (eg {@code "java"}). This is case-sensitive.
*
* @param langId Language ID
*
* @return A language, or null if the name is unknown, or the parameter is null
*/
public @Nullable Language getLanguageById(@Nullable String langId) {
return languagesById.get(langId);
}
/**
* Returns a language version from its {@linkplain Language#getId() language ID}
* (eg {@code "java"}). This is case-sensitive.
*
* @param langId Language ID
* @param version Version ID
*
* @return A language, or null if the name is unknown
*/
public @Nullable LanguageVersion getLanguageVersionById(@Nullable String langId, @Nullable String version) {
Language lang = languagesById.get(langId);
if (lang == null) {
return null;
}
return version == null ? lang.getDefaultVersion()
: lang.getVersion(version);
}
/**
* Returns a language from its {@linkplain Language#getName() full name}
* (eg {@code "Java"}). This is case sensitive.
*
* @param languageName Language name
*
* @return A language, or null if the name is unknown
*/
public @Nullable Language getLanguageByFullName(String languageName) {
return languagesByFullName.get(languageName);
}
/**
* Returns a language from its {@linkplain Language#getId() terse name}
* (eg {@code "java"}). This is case sensitive.
*
* @param terseName Language terse name
*
* @return A language, or null if the name is unknown
*
* @deprecated Use {@link #getLanguageById(String) LanguageRegistry.PMD.getLanguageById}.
*/
@Deprecated
@DeprecatedUntil700
public static @Nullable Language findLanguageByTerseName(@Nullable String terseName) {
return PMD.getLanguageById(terseName);
}
/**
* Returns all languages that support the given extension.
*
* @param extensionWithoutDot A file extension (without '.' prefix)
*
* @deprecated Not replaced, extension will be extended to match full name in PMD 7.
*/
@Deprecated
@DeprecatedUntil700
public static List<Language> findByExtension(String extensionWithoutDot) {
List<Language> languages = new ArrayList<>();
for (Language language : PMD.getLanguages()) {
if (language.hasExtension(extensionWithoutDot)) {
languages.add(language);
}
}
return languages;
}
/**
* Formats the set of languages with the given formatter, sort and
* join everything with commas. Convenience method.
*/
public @NonNull String commaSeparatedList(Function<? super Language, String> languageToString) {
return getLanguages().stream().map(languageToString).sorted().collect(Collectors.joining(", "));
}
@Override
public String toString() {
return "LanguageRegistry(" + commaSeparatedList(Language::getId) + ")";
}
}

View File

@ -488,7 +488,7 @@ final class RuleSetFactory {
"Rule {0}/{1} does not mention attribute language='{2}',"
+ " please mention it explicitly to be compatible with PMD 7",
ruleSetReferenceId.getRuleSetFileName(), rule.getName(),
rule.getLanguage().getTerseName());
rule.getLanguage().getId());
}
ruleSetBuilder.addRule(rule);

View File

@ -301,7 +301,7 @@ public final class RuleSetLoader {
List<String> ruleSetReferenceIds = new ArrayList<>();
for (Language language : languageRegistry.getLanguages()) {
Properties props = new Properties();
rulesetsProperties = "category/" + language.getTerseName() + "/categories.properties";
rulesetsProperties = "category/" + language.getId() + "/categories.properties";
try (InputStream inputStream = resourceLoader.loadClassPathResourceAsStreamOrThrow(rulesetsProperties)) {
props.load(inputStream);
String rulesetFilenames = props.getProperty("rulesets.filenames");

View File

@ -211,7 +211,7 @@ public class RuleSetWriter {
Element ruleElement = createRuleElement();
// language is now a required attribute, unless this is a rule reference
if (clazz != null) {
ruleElement.setAttribute("language", language.getTerseName());
ruleElement.setAttribute("language", language.getId());
}
if (minimumLanguageVersion != null) {
ruleElement.setAttribute("minimumLanguageVersion", minimumLanguageVersion.getVersion());

View File

@ -39,7 +39,7 @@ public class CachedRuleMapper {
*/
public void initialize(final RuleSets rs) {
for (final Rule r : rs.getAllRules()) {
cachedRulesInstances.put(getRuleKey(r.getRuleClass(), r.getName(), r.getLanguage().getTerseName()), r);
cachedRulesInstances.put(getRuleKey(r.getRuleClass(), r.getName(), r.getLanguage().getId()), r);
}
}

View File

@ -130,7 +130,7 @@ public final class CachedRuleViolation implements RuleViolation {
stream.writeUTF(StringUtil.nullToEmpty(violation.getDescription()));
stream.writeUTF(StringUtil.nullToEmpty(violation.getRule().getRuleClass()));
stream.writeUTF(StringUtil.nullToEmpty(violation.getRule().getName()));
stream.writeUTF(StringUtil.nullToEmpty(violation.getRule().getLanguage().getTerseName()));
stream.writeUTF(StringUtil.nullToEmpty(violation.getRule().getLanguage().getId()));
FileLocation location = violation.getLocation();
stream.writeInt(location.getStartPos().getLine());
stream.writeInt(location.getStartPos().getColumn());

View File

@ -52,20 +52,6 @@ public interface Language extends Comparable<Language> {
*/
String getShortName();
/**
* Returns the terse name of this language. This is a short, alphanumeric,
* lowercase name, eg {@code "java"}. It's used to identify the language
* in the ruleset XML, and is also in the package name of the language
* module.
*
* @return The terse name of this language.
*
* @deprecated Use {@link #getId()}
*/
@Deprecated
String getTerseName();
/**
* Returns the ID of this language. This is a short, alphanumeric,
* lowercase name, eg {@code "java"}. It's used to identify the language
@ -74,9 +60,7 @@ public interface Language extends Comparable<Language> {
*
* @return The ID of this language.
*/
default String getId() {
return getTerseName();
}
String getId();
/**
* Returns the list of file extensions associated with this language.

View File

@ -138,7 +138,7 @@ public abstract class LanguageModuleBase implements Language {
}
@Override
public String getTerseName() {
public String getId() {
return meta.id;
}
@ -149,7 +149,7 @@ public abstract class LanguageModuleBase implements Language {
@Override
public String toString() {
return getTerseName();
return getId();
}
@Override

View File

@ -4,12 +4,10 @@
package net.sourceforge.pmd.lang;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
@ -24,7 +22,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sourceforge.pmd.annotation.DeprecatedUntil700;
import net.sourceforge.pmd.cpd.CpdCapableLanguage;
import net.sourceforge.pmd.util.CollectionUtil;
@ -158,22 +155,6 @@ public final class LanguageRegistry implements Iterable<Language> {
return languages;
}
/**
* Returns a language from its {@linkplain Language#getName() full name}
* (eg {@code "Java"}). This is case sensitive.
*
* @param languageName Language name
*
* @return A language, or null if the name is unknown
*
* @deprecated Use {@link #getLanguageByFullName(String) LanguageRegistry.PMD.getLanguageByFullName}
*/
@Deprecated
@DeprecatedUntil700
public static Language getLanguage(String languageName) {
return PMD.getLanguageByFullName(languageName);
}
/**
* Returns a language from its {@linkplain Language#getId() ID}
* (eg {@code "java"}). This is case-sensitive.
@ -216,41 +197,6 @@ public final class LanguageRegistry implements Iterable<Language> {
return languagesByFullName.get(languageName);
}
/**
* Returns a language from its {@linkplain Language#getTerseName() terse name}
* (eg {@code "java"}). This is case sensitive.
*
* @param terseName Language terse name
*
* @return A language, or null if the name is unknown
*
* @deprecated Use {@link #getLanguageById(String) LanguageRegistry.PMD.getLanguageById}.
*/
@Deprecated
@DeprecatedUntil700
public static @Nullable Language findLanguageByTerseName(@Nullable String terseName) {
return PMD.getLanguageById(terseName);
}
/**
* Returns all languages that support the given extension.
*
* @param extensionWithoutDot A file extension (without '.' prefix)
*
* @deprecated Not replaced, extension will be extended to match full name in PMD 7.
*/
@Deprecated
@DeprecatedUntil700
public static List<Language> findByExtension(String extensionWithoutDot) {
List<Language> languages = new ArrayList<>();
for (Language language : PMD.getLanguages()) {
if (language.hasExtension(extensionWithoutDot)) {
languages.add(language);
}
}
return languages;
}
/**
* Formats the set of languages with the given formatter, sort and
* join everything with commas. Convenience method.

View File

@ -76,13 +76,13 @@ public final class LanguageVersion implements Comparable<LanguageVersion> {
}
/**
* Get the terse name of this LanguageVersion. This is Language terse name
* Get the terse name of this LanguageVersion. This is Language id
* appended with the LanguageVersion version if not an empty String.
*
* @return The terse name of this LanguageVersion.
*/
public String getTerseName() {
return version.length() > 0 ? language.getTerseName() + ' ' + version : language.getTerseName();
return version.length() > 0 ? language.getId() + ' ' + version : language.getId();
}
/**

View File

@ -14,7 +14,6 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.annotation.DeprecatedUntil700;
import net.sourceforge.pmd.util.AssertionUtil;
/**
@ -122,21 +121,6 @@ public class LanguageVersionDiscoverer {
this.forcedVersion = forceLanguageVersion;
}
/**
* Get the Languages of a given source file.
*
* @param sourceFile
* The file.
* @return The Languages for the source file, may be empty.
*
* @deprecated PMD 7 avoids using {@link File}.
*/
@Deprecated
@DeprecatedUntil700
public List<Language> getLanguagesForFile(File sourceFile) {
return getLanguagesForFile(sourceFile.getName());
}
/**
* Get the Languages of a given source file.
*

View File

@ -260,7 +260,7 @@ public class RuleFactory {
.error(
message,
attrValue,
language.getTerseName(),
language.getId(),
supportedVersions
);
}

View File

@ -235,7 +235,7 @@ class BaseTestParserImpl {
version = null;
terseName = terseNameAndVersion;
}
Language language = LanguageRegistry.findLanguageByTerseName(terseName);
Language language = LanguageRegistry.PMD.getLanguageById(terseName);
if (language != null) {
if (version == null) {
return language.getDefaultVersion();

View File

@ -158,7 +158,7 @@ public abstract class AbstractRuleSetFactoryTest {
.append(" is missing 'externalInfoURL' attribute\n");
} else {
String expectedExternalInfoURL = "https://docs.pmd-code.org/.+/pmd_rules_"
+ language.getTerseName() + "_"
+ language.getId() + "_"
+ IOUtil.getFilenameBase(fileName)
+ ".html#"
+ rule.getName().toLowerCase(Locale.ROOT);
@ -177,7 +177,7 @@ public abstract class AbstractRuleSetFactoryTest {
}
}
// Proper class name/packaging?
String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group
String expectedClassName = "net.sourceforge.pmd.lang." + language.getId() + ".rule." + group
+ "." + rule.getName() + "Rule";
if (!rule.getRuleClass().equals(expectedClassName)
&& !validXPathClassNames.contains(rule.getRuleClass())) {
@ -309,10 +309,10 @@ public abstract class AbstractRuleSetFactoryTest {
List<String> result = new ArrayList<>();
for (Language language : LanguageRegistry.PMD.getLanguages()) {
if (this.languagesToSkip.contains(language.getTerseName())) {
if (this.languagesToSkip.contains(language.getId())) {
continue;
}
result.addAll(getRuleSetFileNames(language.getTerseName()));
result.addAll(getRuleSetFileNames(language.getId()));
}
return result;