Delete ParserOptions

This commit is contained in:
Clément Fournier
2020-12-13 00:26:41 +01:00
parent 220d7a0d12
commit 2623efbc8a
27 changed files with 113 additions and 378 deletions

View File

@@ -9,7 +9,6 @@ import java.util.List;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ApexParser;
@@ -33,7 +32,7 @@ public class ApexHandler extends AbstractPmdLanguageVersionHandler {
}
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new ApexParser();
}

View File

@@ -9,10 +9,8 @@ import java.util.List;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.AstProcessingStage;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.rule.RuleTargetSelector;
import net.sourceforge.pmd.properties.PropertySource;
import net.sourceforge.pmd.properties.StringProperty;
@@ -252,21 +250,6 @@ public interface Rule extends PropertySource {
*/
void setPriority(RulePriority priority);
/**
* Get the parser options for this Rule. Parser options are used to
* configure the {@link Parser} to create an AST in
* the form the Rule is expecting. Because ParserOptions are mutable, a Rule
* should return a new instance on each call.
*
* @return the parser options
*
* @deprecated This was never implemented and will never be. PMD
* cannot parse files once per rule. Let this method assume
* its default by not overriding it.
*/
@Deprecated
ParserOptions getParserOptions();
/**
* Returns true if this rule depends on the given processing stage

View File

@@ -49,14 +49,9 @@ public interface LanguageVersionHandler {
/**
* Get the default ParserOptions.
*
* @return ParserOptions
* @deprecated This is transitional
*/
default ParserOptions getDefaultParserOptions() {
return new ParserOptions();
}
@Deprecated
default void declareParserTaskProperties(PropertySource source) {
// do nothing
}
@@ -67,13 +62,9 @@ public interface LanguageVersionHandler {
*
* @return Parser
*/
Parser getParser(ParserOptions parserOptions);
Parser getParser();
default Parser getParser() {
return getParser(getDefaultParserOptions());
}
/**
* Get the RuleViolationFactory.

View File

@@ -1,107 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang;
import java.util.Objects;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.properties.AbstractPropertySource;
import net.sourceforge.pmd.properties.PropertyDescriptor;
/**
* Represents a set of configuration options for a {@link Parser}. For each
* unique combination of ParserOptions a Parser will be used to create an AST.
* Therefore, implementations must implement {@link Object#equals(Object)} and
* {@link Object#hashCode()}.
*/
public class ParserOptions {
private String suppressMarker = PMD.SUPPRESS_MARKER;
/**
* Language used to construct environment variable names that match PropertyDescriptors.
*/
private final String languageId;
private final ParserOptionsProperties parserOptionsProperties;
public ParserOptions() {
this.languageId = null;
this.parserOptionsProperties = new ParserOptionsProperties();
}
public ParserOptions(String languageId) {
this.languageId = Objects.requireNonNull(languageId);
this.parserOptionsProperties = new ParserOptionsProperties();
}
protected final void defineProperty(PropertyDescriptor<?> propertyDescriptor) {
parserOptionsProperties.definePropertyDescriptor(propertyDescriptor);
}
protected final <T> void defineProperty(PropertyDescriptor<T> propertyDescriptor, T initialValue) {
defineProperty(propertyDescriptor);
setProperty(propertyDescriptor, initialValue);
}
protected final <T> void setProperty(PropertyDescriptor<T> propertyDescriptor, T initialValue) {
parserOptionsProperties.setProperty(propertyDescriptor, initialValue);
}
public final <T> T getProperty(PropertyDescriptor<T> propertyDescriptor) {
return parserOptionsProperties.getProperty(propertyDescriptor);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final ParserOptions that = (ParserOptions) obj;
return Objects.equals(suppressMarker, that.suppressMarker)
&& Objects.equals(languageId, that.languageId)
&& Objects.equals(parserOptionsProperties, that.parserOptionsProperties);
}
@Override
public int hashCode() {
return Objects.hash(suppressMarker, languageId, parserOptionsProperties);
}
private final class ParserOptionsProperties extends AbstractPropertySource {
@Override
protected String getPropertySourceType() {
return "ParserOptions";
}
@Override
public String getName() {
return ParserOptions.this.getClass().getSimpleName();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ParserOptionsProperties)) {
return false;
}
final ParserOptionsProperties that = (ParserOptionsProperties) obj;
return Objects.equals(getPropertiesByPropertyDescriptor(),
that.getPropertiesByPropertyDescriptor());
}
@Override
public int hashCode() {
return getPropertiesByPropertyDescriptor().hashCode();
}
}
}

View File

@@ -53,12 +53,7 @@ public interface Parser {
private final PropertySource propertySource;
public ParserTask(LanguageVersion lv, String filepath, String sourceText, SemanticErrorReporter reporter) {
this(lv, filepath, sourceText, reporter, PMD.SUPPRESS_MARKER);
}
public ParserTask(LanguageVersion lv, String filepath, String sourceText, SemanticErrorReporter reporter, String commentMarker) {
this.lv = Objects.requireNonNull(lv, "lv was null");
this.filepath = Objects.requireNonNull(filepath, "filepath was null");
this.sourceText = Objects.requireNonNull(sourceText, "sourceText was null");

View File

@@ -12,7 +12,6 @@ import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.properties.MultiValuePropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@@ -182,11 +181,6 @@ public abstract class AbstractDelegateRule implements Rule {
rule.setPriority(priority);
}
@Override
public ParserOptions getParserOptions() {
return rule.getParserOptions();
}
@Override
public void definePropertyDescriptor(PropertyDescriptor<?> propertyDescriptor) throws IllegalArgumentException {
rule.definePropertyDescriptor(propertyDescriptor);

View File

@@ -17,7 +17,6 @@ import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.RootNode;
import net.sourceforge.pmd.properties.AbstractPropertySource;
@@ -227,18 +226,6 @@ public abstract class AbstractRule extends AbstractPropertySource implements Rul
this.priority = priority;
}
/**
* This implementation returns a new instance of {@link ParserOptions} using
* default settings.
*
* @see Rule#setPriority(RulePriority)
*/
@Override
@Deprecated
public ParserOptions getParserOptions() {
return new ParserOptions();
}
private Set<Class<? extends Node>> getClassRuleChainVisits() {
if (classRuleChainVisits.isEmpty() && ruleChainVisits.isEmpty()) {

View File

@@ -49,7 +49,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return task -> {
DummyRoot node = new DummyRoot();
node.setCoords(1, 1, 2, 10);
@@ -64,7 +64,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
public static class HandlerWithParserThatThrows extends Handler {
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return task -> {
throw new AssertionError("test error while parsing");
};

View File

@@ -8,7 +8,6 @@ import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.JavaParser;
@@ -63,7 +62,7 @@ public class JavaLanguageHandler extends AbstractPmdLanguageVersionHandler {
}
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new JavaParser(levelChecker);
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.ecmascript;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.ecmascript.ast.EcmascriptParser;
@@ -18,7 +17,7 @@ class EcmascriptHandler extends AbstractPmdLanguageVersionHandler {
}
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new EcmascriptParser(rhinoVersion);
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.jsp;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.jsp.ast.JspParser;
@@ -17,7 +16,7 @@ import net.sourceforge.pmd.lang.jsp.ast.JspParser;
public class JspHandler extends AbstractPmdLanguageVersionHandler {
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new JspParser();
}

View File

@@ -13,6 +13,8 @@ import java.io.File
import java.io.InputStream
import java.io.StringReader
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.util.function.Consumer
/**
@@ -30,7 +32,6 @@ abstract class BaseParsingHelper<Self : BaseParsingHelper<Self, T>, T : RootNode
val defaultVerString: String?,
val resourceLoader: Class<*>?,
val resourcePrefix: String,
val parserOptions: ParserOptions? = null,
val configureParser: (PropertySource) -> Unit = {},
) {
companion object {
@@ -94,13 +95,9 @@ abstract class BaseParsingHelper<Self : BaseParsingHelper<Self, T>, T : RootNode
/**
* Returns an instance of [Self] for which the [parse] methods use
* the provided [parserOptions].
* Returns an instance of [Self] which configures the parser task with the
* given closure.
*/
fun withParserOptions(parserOptions: ParserOptions?): Self =
clone(params.copy(parserOptions = parserOptions))
fun withParserConfig(configFun: Consumer<PropertySource>): Self =
clone(params.copy(configureParser = { configFun.accept(it) }))
@@ -126,8 +123,7 @@ abstract class BaseParsingHelper<Self : BaseParsingHelper<Self, T>, T : RootNode
fun parse(sourceCode: String, version: String? = null): T {
val lversion = if (version == null) defaultVersion else getVersion(version)
val handler = lversion.languageVersionHandler
val options = params.parserOptions ?: handler.defaultParserOptions
val parser = handler.getParser(options)
val parser = handler.parser
val source = DataSource.forString(sourceCode, FileAnalysisException.NO_FILE_NAME)
val toString = DataSource.readToString(source, StandardCharsets.UTF_8)
val task = Parser.ParserTask(lversion, FileAnalysisException.NO_FILE_NAME, toString, SemanticErrorReporter.noop())
@@ -175,6 +171,13 @@ abstract class BaseParsingHelper<Self : BaseParsingHelper<Self, T>, T : RootNode
open fun parseResource(resource: String, version: String? = null): T =
parse(readResource(resource), version)
/**
* Fetches and [parse]s the [path].
*/
@JvmOverloads
open fun parseFile(path: Path, version: String? = null): T =
parse(IOUtils.toString(Files.newBufferedReader(path)), version)
/**
* Fetches the source of the given [clazz].
*/

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.modelica;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.modelica.ast.ModelicaParser;
import net.sourceforge.pmd.lang.modelica.internal.ModelicaProcessingStage;
@@ -19,7 +18,7 @@ public class ModelicaHandler extends AbstractPmdLanguageVersionHandler {
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new ModelicaParser();
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.plsql;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.plsql.ast.PLSQLParser;
@@ -23,7 +22,7 @@ public class PLSQLHandler extends AbstractPmdLanguageVersionHandler {
}
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new PLSQLParser();
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.scala;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.scala.ast.ScalaParser;
import scala.meta.Dialect;
@@ -38,7 +37,7 @@ public class ScalaLanguageHandler extends AbstractPmdLanguageVersionHandler {
@Override
public ScalaParser getParser(ParserOptions parserOptions) {
public ScalaParser getParser() {
return new ScalaParser(dialect);
}
}

View File

@@ -5,14 +5,13 @@
package net.sourceforge.pmd.lang.swift;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.swift.ast.PmdSwiftParser;
public class SwiftHandler extends AbstractPmdLanguageVersionHandler {
@Override
public Parser getParser(final ParserOptions parserOptions) {
public Parser getParser() {
return new PmdSwiftParser();
}
}

View File

@@ -1,31 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang;
/**
* Unit tests for {@link ParserOptions}.
* @deprecated for removal in PMD 7.0. Use {@link ParserOptionsTestUtils}.
*/
@Deprecated
public class ParserOptionsTest {
/**
* Verify equals and hashCode for 4 {@link ParserOptions} instances. The
* given options should be as follows: 1 and 3 are equals, as are 2 and 4.
*
* @param options1
* first option instance - equals third
* @param options2
* second option instance - equals fourth
* @param options3
* third option instance - equals first
* @param options4
* fourth option instance - equals second
*/
public static void verifyOptionsEqualsHashcode(ParserOptions options1, ParserOptions options2,
ParserOptions options3, ParserOptions options4) {
ParserOptionsTestUtils.verifyOptionsEqualsHashcode(options1, options2, options3, options4);
}
}

View File

@@ -1,65 +0,0 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang;
import org.junit.Assert;
public final class ParserOptionsTestUtils {
private ParserOptionsTestUtils() {
}
/**
* Verify equals and hashCode for 4 {@link ParserOptions} instances. The
* given options should be as follows: 1 and 3 are equals, as are 2 and 4.
*
* @param options1
* first option instance - equals third
* @param options2
* second option instance - equals fourth
* @param options3
* third option instance - equals first
* @param options4
* fourth option instance - equals second
*/
public static void verifyOptionsEqualsHashcode(ParserOptions options1, ParserOptions options2,
ParserOptions options3, ParserOptions options4) {
// Objects should be different
Assert.assertNotSame(options1, options2);
Assert.assertNotSame(options1, options2);
Assert.assertNotSame(options1, options3);
Assert.assertNotSame(options2, options3);
Assert.assertNotSame(options2, options4);
Assert.assertNotSame(options3, options4);
// Check all 16 equality combinations
Assert.assertEquals(options1, options1);
Assert.assertNotEquals(options1, options2);
Assert.assertEquals(options1, options3);
Assert.assertNotEquals(options1, options4);
Assert.assertNotEquals(options2, options1);
Assert.assertEquals(options2, options2);
Assert.assertNotEquals(options2, options3);
Assert.assertEquals(options2, options4);
Assert.assertEquals(options3, options1);
Assert.assertNotEquals(options3, options2);
Assert.assertEquals(options3, options3);
Assert.assertNotEquals(options3, options4);
Assert.assertNotEquals(options4, options1);
Assert.assertEquals(options4, options2);
Assert.assertNotEquals(options4, options3);
Assert.assertEquals(options4, options4);
// Hashcodes should match up
Assert.assertNotEquals(options1.hashCode(), options2.hashCode());
Assert.assertEquals(options1.hashCode(), options3.hashCode());
Assert.assertNotEquals(options1.hashCode(), options4.hashCode());
Assert.assertNotEquals(options2.hashCode(), options3.hashCode());
Assert.assertEquals(options2.hashCode(), options4.hashCode());
Assert.assertNotEquals(options3.hashCode(), options4.hashCode());
}
}

View File

@@ -10,7 +10,6 @@ import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.BaseLanguageModule;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.AstInfo;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.ast.RootNode;
@@ -45,7 +44,7 @@ public class DummyLanguageModule extends BaseLanguageModule {
}
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return task -> {
DummyRootNode node = new DummyRootNode();
node.setCoords(1, 1, 1, 2);

View File

@@ -9,7 +9,6 @@ import java.util.Collections;
import java.util.List;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.vf.ast.VfParser;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@@ -46,7 +45,7 @@ public class VfHandler extends AbstractPmdLanguageVersionHandler {
.build();
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new VfParser();
}

View File

@@ -12,16 +12,17 @@ import java.nio.file.Path;
import java.util.List;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.exception.ContextedRuntimeException;
import org.apache.commons.lang3.tuple.Pair;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.apex.ApexLanguageModule;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;
import net.sourceforge.pmd.lang.ast.SemanticErrorReporter;
import net.sourceforge.pmd.lang.vf.DataType;
import apex.jorje.semantic.symbol.type.BasicType;
@@ -47,18 +48,12 @@ class ApexClassPropertyTypes extends SalesforceFieldTypes {
for (Path apexDirectory : apexDirectories) {
Path apexFilePath = apexDirectory.resolve(className + APEX_CLASS_FILE_SUFFIX);
if (Files.exists(apexFilePath) && Files.isRegularFile(apexFilePath)) {
Parser parser = getApexParser();
try (BufferedReader reader = Files.newBufferedReader(apexFilePath, StandardCharsets.UTF_8)) {
Node node = parser.parse(apexFilePath.toString(), reader);
ApexClassPropertyTypesVisitor visitor = new ApexClassPropertyTypesVisitor();
visitor.visit((ApexNode<?>) node, null);
for (Pair<String, BasicType> variable : visitor.getVariables()) {
putDataType(variable.getKey(), DataType.fromBasicType(variable.getValue()));
}
} catch (IOException e) {
throw new ContextedRuntimeException(e)
.addContextValue("expression", expression)
.addContextValue("apexFilePath", apexFilePath);
Node node = parse(expression, apexFilePath);
ApexClassPropertyTypesVisitor visitor = new ApexClassPropertyTypesVisitor();
node.acceptVisitor(visitor, null);
for (Pair<String, BasicType> variable : visitor.getVariables()) {
putDataType(variable.getKey(), DataType.fromBasicType(variable.getValue()));
}
if (containsExpression(expression)) {
@@ -70,6 +65,29 @@ class ApexClassPropertyTypes extends SalesforceFieldTypes {
}
}
private Node parse(String expression, Path apexFilePath) {
String fileText;
try (BufferedReader reader = Files.newBufferedReader(apexFilePath, StandardCharsets.UTF_8)) {
fileText = IOUtils.toString(reader);
} catch (IOException e) {
throw new ContextedRuntimeException(e)
.addContextValue("expression", expression)
.addContextValue("apexFilePath", apexFilePath);
}
LanguageVersion languageVersion = LanguageRegistry.getLanguage(ApexLanguageModule.NAME).getDefaultVersion();
Parser parser = languageVersion.getLanguageVersionHandler().getParser();
ParserTask task = new ParserTask(
languageVersion,
apexFilePath.toString(),
fileText,
SemanticErrorReporter.noop()
);
return parser.parse(task);
}
@Override
protected DataType putDataType(String name, DataType dataType) {
DataType previousType = super.putDataType(name, dataType);
@@ -91,9 +109,4 @@ class ApexClassPropertyTypes extends SalesforceFieldTypes {
return previousType;
}
private Parser getApexParser() {
LanguageVersion languageVersion = LanguageRegistry.getLanguage(ApexLanguageModule.NAME).getDefaultVersion();
ParserOptions parserOptions = languageVersion.getLanguageVersionHandler().getDefaultParserOptions();
return languageVersion.getLanguageVersionHandler().getParser(parserOptions);
}
}

View File

@@ -13,8 +13,7 @@ import org.apache.commons.lang3.tuple.Pair;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorAdapter;
import net.sourceforge.pmd.lang.apex.ast.ApexVisitorBase;
import apex.jorje.semantic.symbol.member.method.Generated;
import apex.jorje.semantic.symbol.member.method.MethodInfo;
@@ -23,7 +22,7 @@ import apex.jorje.semantic.symbol.type.BasicType;
/**
* Visits an Apex class to determine a mapping of referenceable expressions to expression type.
*/
final class ApexClassPropertyTypesVisitor extends ApexParserVisitorAdapter {
final class ApexClassPropertyTypesVisitor extends ApexVisitorBase<Void, Void> {
/**
* Prefix for standard bean type getters, i.e. getFoo
@@ -54,7 +53,7 @@ final class ApexClassPropertyTypesVisitor extends ApexParserVisitorAdapter {
* Visualforce page.
*/
@Override
public Object visit(ASTMethod node, Object data) {
public Void visit(ASTMethod node, Void data) {
MethodInfo mi = node.getNode().getMethodInfo();
if (mi.getParameterTypes().isEmpty()
&& isVisibleToVisualForce(node)
@@ -76,7 +75,7 @@ final class ApexClassPropertyTypesVisitor extends ApexParserVisitorAdapter {
variables.add(Pair.of(sb.toString(), mi.getReturnType().getBasicType()));
}
return super.visit((ApexNode<?>) node, data);
return visitApexNode(node, data);
}
/**

View File

@@ -5,28 +5,25 @@
package net.sourceforge.pmd.lang.vf.ast;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.Test;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.apex.ApexLanguageModule;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;
import net.sourceforge.pmd.lang.ast.SemanticErrorReporter;
import net.sourceforge.pmd.lang.vf.VFTestUtils;
import apex.jorje.semantic.symbol.type.BasicType;
@@ -35,17 +32,16 @@ public class ApexClassPropertyTypesVisitorTest {
@Test
public void testApexClassIsProperlyParsed() throws IOException {
LanguageVersion languageVersion = LanguageRegistry.getLanguage(ApexLanguageModule.NAME).getDefaultVersion();
ParserOptions parserOptions = languageVersion.getLanguageVersionHandler().getDefaultParserOptions();
Parser parser = languageVersion.getLanguageVersionHandler().getParser(parserOptions);
Parser parser = languageVersion.getLanguageVersionHandler().getParser();
Path apexPath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.SFDX, VFTestUtils.MetadataType.Apex)
.resolve("ApexController.cls").toAbsolutePath();
ParserTask task = new ParserTask(languageVersion,
apexPath.toString(),
IOUtils.toString(Files.newBufferedReader(apexPath)),
SemanticErrorReporter.noop());
ApexClassPropertyTypesVisitor visitor = new ApexClassPropertyTypesVisitor();
try (BufferedReader reader = Files.newBufferedReader(apexPath, StandardCharsets.UTF_8)) {
Node node = parser.parse(apexPath.toString(), reader);
assertNotNull(node);
visitor.visit((ApexNode<?>) node, null);
}
parser.parse(task).acceptVisitor(visitor, null);
List<Pair<String, BasicType>> variables = visitor.getVariables();
assertEquals(7, variables.size());

View File

@@ -9,8 +9,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
@@ -20,15 +18,10 @@ import java.util.Map.Entry;
import org.junit.Test;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.NodeStream;
import net.sourceforge.pmd.lang.vf.DataType;
import net.sourceforge.pmd.lang.vf.VFTestUtils;
import net.sourceforge.pmd.lang.vf.VfLanguageModule;
import net.sourceforge.pmd.util.treeexport.XmlTreeRenderer;
public class VfExpressionTypeVisitorTest {
@@ -60,7 +53,7 @@ public class VfExpressionTypeVisitorTest {
* Strings that use dot notation(Account.CreatedDate) result in ASTIdentifier nodes
*/
@Test
public void testXpathQueryForCustomFieldIdentifiers() throws FileNotFoundException {
public void testXpathQueryForCustomFieldIdentifiers() {
Node rootNode = compile("StandardAccount.page");
for (Map.Entry<String, DataType> entry : EXPECTED_CUSTOM_FIELD_DATA_TYPES.entrySet()) {
@@ -82,7 +75,7 @@ public class VfExpressionTypeVisitorTest {
* creates ambiguous situations with Apex methods that return Maps. This may be addressed in a future release.
*/
@Test
public void testXpathQueryForCustomFieldLiteralsHaveNullDataType() throws FileNotFoundException {
public void testXpathQueryForCustomFieldLiteralsHaveNullDataType() {
Node rootNode = compile("StandardAccount.page");
for (Map.Entry<String, DataType> entry : EXPECTED_CUSTOM_FIELD_DATA_TYPES.entrySet()) {
@@ -107,7 +100,7 @@ public class VfExpressionTypeVisitorTest {
* Nodes where the DataType can't be determined should have a null DataType
*/
@Test
public void testDataTypeForCustomFieldsNotFound() throws FileNotFoundException {
public void testDataTypeForCustomFieldsNotFound() {
Node rootNode = compile("StandardAccount.page");
checkNodes(rootNode.descendants(ASTIdentifier.class)
@@ -129,7 +122,7 @@ public class VfExpressionTypeVisitorTest {
* Apex properties result in ASTIdentifier nodes
*/
@Test
public void testXpathQueryForProperties() throws FileNotFoundException {
public void testXpathQueryForProperties() {
Node rootNode = compile("ApexController.page");
for (Map.Entry<String, DataType> entry : EXPECTED_APEX_DATA_TYPES.entrySet()) {
@@ -157,7 +150,7 @@ public class VfExpressionTypeVisitorTest {
* Nodes where the DataType can't be determined should have a null DataType
*/
@Test
public void testDataTypeForApexPropertiesNotFound() throws FileNotFoundException {
public void testDataTypeForApexPropertiesNotFound() {
Node rootNode = compile("ApexController.page");
// Each string appears twice, it is set on a "value" attribute and inline
@@ -165,22 +158,18 @@ public class VfExpressionTypeVisitorTest {
.filterMatching(ASTIdentifier::getImage, "NotFoundProp"));
}
private Node compile(String pageName) throws FileNotFoundException {
private Node compile(String pageName) {
return compile(pageName, false);
}
private Node compile(String pageName, boolean renderAST) throws FileNotFoundException {
private Node compile(String pageName, boolean renderAST) {
Path vfPagePath = VFTestUtils.getMetadataPath(this, VFTestUtils.MetadataFormat.SFDX, VFTestUtils.MetadataType.Vf)
.resolve(pageName);
return compile(vfPagePath, renderAST);
}
private Node compile(Path vfPagePath, boolean renderAST) throws FileNotFoundException {
LanguageVersion languageVersion = LanguageRegistry.getLanguage(VfLanguageModule.NAME).getDefaultVersion();
ParserOptions parserOptions = languageVersion.getLanguageVersionHandler().getDefaultParserOptions();
Parser parser = languageVersion.getLanguageVersionHandler().getParser(parserOptions);
Node node = parser.parse(vfPagePath.toString(), new FileReader(vfPagePath.toFile()));
private Node compile(Path vfPagePath, boolean renderAST) {
Node node = VfParsingHelper.DEFAULT.parseFile(vfPagePath);
assertNotNull(node);
if (renderAST) {

View File

@@ -4,34 +4,37 @@
package net.sourceforge.pmd.lang.vf.rule.security;
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.PMDException;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSets;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.ast.Parser.ParserTask;
import net.sourceforge.pmd.lang.ast.SemanticErrorReporter;
import net.sourceforge.pmd.lang.vf.VFTestUtils;
import net.sourceforge.pmd.lang.vf.VfLanguageModule;
import net.sourceforge.pmd.testframework.PmdRuleTst;
import net.sourceforge.pmd.util.datasource.FileDataSource;
public class VfUnescapeElTest extends PmdRuleTst {
public static final String EXPECTED_RULE_MESSAGE = "Avoid unescaped user controlled content in EL";
@@ -118,26 +121,28 @@ public class VfUnescapeElTest extends PmdRuleTst {
}
/**
* Runs a rule against a Visualforce page on the file system. This code is based on
* {@link net.sourceforge.pmd.testframework.RuleTst#runTestFromString(String, Rule, Report, LanguageVersion, boolean)}
* Runs a rule against a Visualforce page on the file system.
*/
private Report runRule(Path vfPagePath) throws FileNotFoundException, PMDException {
private Report runRule(Path vfPagePath) throws IOException {
LanguageVersion languageVersion = LanguageRegistry.getLanguage(VfLanguageModule.NAME).getDefaultVersion();
ParserOptions parserOptions = languageVersion.getLanguageVersionHandler().getDefaultParserOptions();
Parser parser = languageVersion.getLanguageVersionHandler().getParser(parserOptions);
ParserTask task = new ParserTask(languageVersion,
vfPagePath.toString(),
IOUtils.toString(Files.newBufferedReader(vfPagePath)),
SemanticErrorReporter.noop());
Node node = parser.parse(vfPagePath.toString(), new FileReader(vfPagePath.toFile()));
Parser parser = languageVersion.getLanguageVersionHandler().getParser();
Node node = parser.parse(task);
assertNotNull(node);
// BEGIN Based on RuleTst class
PMD p = new PMD();
p.getConfiguration().setDefaultLanguageVersion(languageVersion);
p.getConfiguration().setIgnoreIncrementalAnalysis(true);
PMDConfiguration config = new PMDConfiguration();
config.setDefaultLanguageVersion(languageVersion);
config.setIgnoreIncrementalAnalysis(true);
// simple class loader, that doesn't delegate to parent.
// this allows us in the tests to simulate PMD run without
// auxclasspath, not even the classes from the test dependencies
// will be found.
p.getConfiguration().setClassLoader(new ClassLoader() {
config.setClassLoader(new ClassLoader() {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("java.") || name.startsWith("javax.")) {
@@ -146,18 +151,13 @@ public class VfUnescapeElTest extends PmdRuleTst {
throw new ClassNotFoundException(name);
}
});
Rule rule = findRule("category/vf/security.xml", "VfUnescapeEl");
Report report = new Report();
RuleContext ctx = new RuleContext();
ctx.setReport(report);
ctx.setSourceCodeFile(vfPagePath.toFile());
ctx.setLanguageVersion(languageVersion);
ctx.setIgnoreExceptions(false);
RuleSet rules = RuleSet.forSingleRule(rule);
p.getSourceCodeProcessor().processSourceCode(new FileReader(vfPagePath.toFile()), new RuleSets(rules), ctx);
// END Based on RuleTst class
return report;
return PMD.processFiles(
config,
listOf(RuleSet.forSingleRule(rule)),
listOf(new FileDataSource(vfPagePath.toFile())),
Collections.emptyList()
);
}
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.vm;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
import net.sourceforge.pmd.lang.vm.ast.VmParser;
@@ -17,7 +16,7 @@ public class VmHandler extends AbstractPmdLanguageVersionHandler {
@Override
public Parser getParser(final ParserOptions parserOptions) {
public Parser getParser() {
return new VmParser();
}

View File

@@ -5,7 +5,6 @@
package net.sourceforge.pmd.lang.xml;
import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.ast.Parser;
/**
@@ -14,7 +13,7 @@ import net.sourceforge.pmd.lang.ast.Parser;
public class XmlHandler extends AbstractPmdLanguageVersionHandler {
@Override
public Parser getParser(ParserOptions parserOptions) {
public Parser getParser() {
return new XmlParser();
}