Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to latest pmd 7 changes #57

Merged
merged 2 commits into from
Mar 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public Val<Integer> numAvailableMetrics() {


private ObservableList<MetricResult<?>> evaluateAllMetrics(Node n) {
LanguageMetricsProvider provider = getGlobalLanguageVersion().getLanguageVersionHandler().getLanguageMetricsProvider();
LanguageMetricsProvider provider = n.getAstInfo().getLanguageProcessor().services().getLanguageMetricsProvider();
if (provider == null) {
return FXCollections.emptyObservableList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import org.reactfx.value.Val;

import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
import net.sourceforge.pmd.util.fxdesigner.SourceEditorController;
import net.sourceforge.pmd.util.fxdesigner.app.services.AppServiceDescriptor;
Expand Down Expand Up @@ -50,11 +48,6 @@ default <T> T getService(AppServiceDescriptor<T> descriptor) {
}


default LanguageVersion getGlobalLanguageVersion() {
return getService(DesignerRoot.AST_MANAGER).languageVersionProperty().getValue();
}


/**
* The language is now global to the app.
*/
Expand All @@ -65,9 +58,8 @@ default LanguageVersion getGlobalLanguageVersion() {

default Val<DesignerBindings> languageBindingsProperty() {
return getService(DesignerRoot.AST_MANAGER)
.languageVersionProperty()
.map(LanguageVersion::getLanguageVersionHandler)
.map(LanguageVersionHandler::getDesignerBindings);
.languageProcessorProperty()
.map(lp -> lp.services().getDesignerBindings());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public Subscription init(ASTManager astManager) {

try {
List<Node> results = XPathEvaluator.evaluateQuery(compil,
astManager.languageVersionProperty().getValue(),
query.getVersion(),
query.getExpression(),
props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.reactfx.value.Val;
import org.reactfx.value.Var;

import net.sourceforge.pmd.lang.LanguageProcessor;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.document.TextDocument;
Expand Down Expand Up @@ -43,6 +44,8 @@ public interface ASTManager extends ApplicationComponent, SettingsOwner {

Val<LanguageVersion> languageVersionProperty();

Val<LanguageProcessor> languageProcessorProperty();


Val<Node> compilationUnitProperty();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,26 @@

import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.reactfx.value.SuspendableVar;
import org.reactfx.value.Val;
import org.reactfx.value.Var;

import org.slf4j.event.Level;

import net.sourceforge.pmd.lang.JvmLanguagePropertyBundle;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageProcessor;
import net.sourceforge.pmd.lang.LanguageProcessorRegistry;
import net.sourceforge.pmd.lang.LanguagePropertyBundle;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;
import net.sourceforge.pmd.lang.ast.RootNode;
Expand All @@ -33,6 +41,7 @@
import net.sourceforge.pmd.util.fxdesigner.model.ParseAbortedException;
import net.sourceforge.pmd.util.fxdesigner.util.AuxLanguageRegistry;
import net.sourceforge.pmd.util.fxdesigner.util.Tuple3;
import net.sourceforge.pmd.util.log.MessageReporter;


/**
Expand All @@ -43,6 +52,25 @@
*/
public class ASTManagerImpl implements ASTManager {

public static final MessageReporter NOOP_REPORTER = new MessageReporter() { // todo replace with MessageReporter.noop
@Override
public boolean isLoggable(Level level) {
return false;
}


@Override
public void logEx(Level level, @Nullable String s, Object[] objects, @Nullable Throwable throwable) {
// noop
}


@Override
public int numErrors() {
return 0;
}
};

private final DesignerRoot designerRoot;

private final Var<ClassLoader> auxclasspathClassLoader = Var.newSimpleVar(null);
Expand All @@ -60,6 +88,7 @@ public class ASTManagerImpl implements ASTManager {
*/
private final SuspendableVar<String> sourceCode = Var.newSimpleVar("").suspendable();
private final SuspendableVar<TextDocument> sourceDocument = Var.newSimpleVar(TextDocument.readOnlyString("", languageVersion.getValue())).suspendable();
private final SuspendableVar<LanguageProcessorRegistry> lpRegistry = Var.<LanguageProcessorRegistry>newSimpleVar(null).suspendable();

private final Var<ParseAbortedException> currentException = Var.newSimpleVar(null);

Expand Down Expand Up @@ -93,7 +122,7 @@ public ASTManagerImpl(DesignerRoot owner) {

Node updated;
try {
updated = refreshAST(this, source, version, classLoader).orElse(null);
updated = refreshAST(this, source, version, refreshRegistry(version, classLoader)).orElse(null);
currentException.setValue(null);
} catch (ParseAbortedException e) {
updated = null;
Expand Down Expand Up @@ -158,16 +187,27 @@ public Var<Map<String, String>> ruleProperties() {
return ruleProperties;
}


@Override
public Var<LanguageVersion> languageVersionProperty() {
return languageVersion;
}


@Override
public Val<LanguageProcessor> languageProcessorProperty() {
return lpRegistry.mapDynamic(
languageVersionProperty().map(LanguageVersion::getLanguage)
.map(l -> lp -> lp.getProcessor(l))
);
}


public LanguageVersion getLanguageVersion() {
return languageVersion.getValue();
}


public void setLanguageVersion(LanguageVersion version) {
this.languageVersion.setValue(version);
}
Expand All @@ -181,11 +221,51 @@ public Val<Node> compilationUnitProperty() {
return nodeVal;
}


@Override
public Var<ParseAbortedException> currentExceptionProperty() {
return currentException;
}


private LanguageProcessorRegistry refreshRegistry(LanguageVersion version, ClassLoader classLoader) {
LanguageProcessorRegistry current = lpRegistry.getValue();
if (current == null) {
Map<Language, LanguagePropertyBundle> langProperties = new HashMap<>();
LanguagePropertyBundle bundle = version.getLanguage().newPropertyBundle();
bundle.setLanguageVersion(version.getVersion());
if (bundle instanceof JvmLanguagePropertyBundle) {
((JvmLanguagePropertyBundle) bundle).setClassLoader(classLoader);
}

langProperties.put(version.getLanguage(), bundle);

LanguageRegistry languages =
AuxLanguageRegistry.supportedLangs()
.getDependenciesOf(version.getLanguage());

LanguageProcessorRegistry newRegistry =
LanguageProcessorRegistry.create(languages,
langProperties,
NOOP_REPORTER);
lpRegistry.setValue(newRegistry);
return newRegistry;
}

// already created, need to check that the version is the same
if (!current.getLanguages().getLanguages().contains(version.getLanguage())
|| !current.getProcessor(version.getLanguage()).getLanguageVersion().equals(version)) {
// current is invalid, recreate it
current.close();
lpRegistry.setValue(null);
return refreshRegistry(version, classLoader);
}

// the current one is fine
return current;
}


/**
* Refreshes the compilation unit given the current state of the model.
*
Expand All @@ -194,28 +274,29 @@ public Var<ParseAbortedException> currentExceptionProperty() {
private static Optional<Node> refreshAST(ApplicationComponent component,
String source,
LanguageVersion version,
ClassLoader classLoader) throws ParseAbortedException {
LanguageProcessorRegistry lpRegistry) throws ParseAbortedException {

String dummyFilePath = "dummy." + version.getLanguage().getExtensions().get(0);
TextDocument textDocument = TextDocument.readOnlyString(source, dummyFilePath, version);
LanguageVersionHandler handler = version.getLanguageVersionHandler();

ParserTask task = new ParserTask(
textDocument,
SemanticErrorReporter.noop(),
classLoader
lpRegistry
);

LanguageProcessor processor = lpRegistry.getProcessor(version.getLanguage());
RootNode node;
try {
node = handler.getParser().parse(task);
node = processor.services().getParser().parse(task);
} catch (Exception e) {
component.logUserException(e, Category.PARSE_EXCEPTION);
throw new ParseAbortedException(e);
}

// Notify that the parse went OK so we can avoid logging very recent exceptions

component.raiseParsableSourceFlag(() -> "Param hash: " + Objects.hash(source, version, classLoader));
component.raiseParsableSourceFlag(() -> "Param hash: " + Objects.hash(source, version, lpRegistry));

return Optional.of(node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@

import org.apache.commons.lang3.StringUtils;

import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.xpath.XPathVersion;
import net.sourceforge.pmd.lang.rule.xpath.internal.DeprecatedAttrLogger; // NOPMD
import net.sourceforge.pmd.lang.rule.xpath.internal.SaxonXPathRuleQuery; // NOPMD
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.util.fxdesigner.app.ApplicationComponent;
import net.sourceforge.pmd.util.fxdesigner.app.DesignerRoot;


Expand All @@ -44,14 +42,12 @@ private XPathEvaluator() {
* @return The results, or an empty list if there was an error
*/
public static List<Node> simpleEvaluate(DesignerRoot root, String query) {
ApplicationComponent component = () -> root;
return root.getService(DesignerRoot.AST_MANAGER)
.compilationUnitProperty()
.getOpt()
.map(n -> {
try {
return evaluateQuery(n,
component.getGlobalLanguageVersion(),
XPathVersion.DEFAULT,
query,
emptyMap(),
Expand All @@ -69,15 +65,13 @@ public static List<Node> simpleEvaluate(DesignerRoot root, String query) {
* no side effects.
*
* @param compilationUnit AST root
* @param languageVersion language version
* @param xpathVersion XPath version
* @param xpathQuery XPath query
* @param properties Properties of the rule
*
* @throws XPathEvaluationException if there was an error during the evaluation. The cause is preserved
*/
public static List<Node> evaluateQuery(Node compilationUnit,
LanguageVersion languageVersion,
XPathVersion xpathVersion,
String xpathQuery,
Map<String, String> propertyValues,
Expand All @@ -99,7 +93,7 @@ public static List<Node> evaluateQuery(Node compilationUnit,
xpathQuery,
xpathVersion,
allProperties,
languageVersion.getLanguageVersionHandler().getXPathHandler(),
compilationUnit.getAstInfo().getLanguageProcessor().services().getXPathHandler(),
DeprecatedAttrLogger.noop()
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public class LiveViolationRecord implements SettingsOwner, Comparable<LiveViolat
private int line;


// this ctor is used by the thing that restores application state
@SuppressWarnings("unused")
public LiveViolationRecord() {
this(-1, TextRegion.caretAt(0), null);
}

public LiveViolationRecord(@NonNull TextRegion region, @Nullable String message) {
this(-1, region, message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@

import net.sourceforge.pmd.lang.document.TextDocument;
import net.sourceforge.pmd.lang.document.TextRegion;
import net.sourceforge.pmd.util.fxdesigner.util.AuxLanguageRegistry;
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
import net.sourceforge.pmd.util.fxdesigner.util.PlainTextLanguage;

public class TestXmlDumper {

Expand Down Expand Up @@ -100,7 +100,7 @@ private void appendSingle(Element testCode, LiveTestCase descriptor, Document do
Element linenos = doc.createElementNS(NS, "expected-linenumbers");

// create a text doc just to ask for line numbers
TextDocument textDocument = TextDocument.readOnlyString(descriptor.getSource(), PlainTextLanguage.INSTANCE.getDefaultVersion());
TextDocument textDocument = TextDocument.readOnlyString(descriptor.getSource(), AuxLanguageRegistry.plainTextLanguage().getDefaultVersion());

String joined = expectedViolations
.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import net.sourceforge.pmd.util.fxdesigner.model.ObservableRuleBuilder;
import net.sourceforge.pmd.util.fxdesigner.util.AuxLanguageRegistry;
import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil;
import net.sourceforge.pmd.util.fxdesigner.util.PlainTextLanguage;

public class TestXmlParser {

Expand Down Expand Up @@ -188,7 +187,7 @@ private static LiveTestCase fromDescriptor(
// create a document just to map source lines to regions
// language is irrelevant so we use plain text
@SuppressWarnings("PMD.CloseResource")
TextDocument doc = TextDocument.readOnlyString(code, PlainTextLanguage.INSTANCE.getDefaultVersion());
TextDocument doc = TextDocument.readOnlyString(code, AuxLanguageRegistry.plainTextLanguage().getDefaultVersion());

for (int i = 0; i < expectedProblems; i++) {
String m = messages.size() > i ? messages.get(i) : null;
Expand Down
Loading