Only attempt loading once
This commit is contained in:
1 parent
97c8c3b365
commit
cf3ed1cd04
3 files changed
+76
-34
No files matched your search
@@ -4,13 +4,10 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileAnalysis;
|
||||
import net.sourceforge.pmd.lang.ast.AstInfo;
|
||||
@@ -25,13 +22,13 @@ import com.nawforce.common.diagnostics.Issue;
|
||||
public final class ASTApexFile extends AbstractApexNode<AstNode> implements RootNode {
|
||||
|
||||
private final AstInfo<ASTApexFile> astInfo;
|
||||
private final @Nullable ApexMultifileAnalysis multifileAnalysis;
|
||||
private final @NonNull ApexMultifileAnalysis multifileAnalysis;
|
||||
|
||||
ASTApexFile(SourceCodePositioner source,
|
||||
ParserTask task,
|
||||
AbstractApexNode<? extends Compilation> child,
|
||||
Map<Integer, String> suppressMap,
|
||||
@Nullable ApexMultifileAnalysis multifileAnalysis) {
|
||||
@NonNull ApexMultifileAnalysis multifileAnalysis) {
|
||||
super(child.getNode());
|
||||
this.astInfo = new AstInfo<>(task, this, suppressMap);
|
||||
addChild(child, 0);
|
||||
@@ -77,10 +74,6 @@ public final class ASTApexFile extends AbstractApexNode<AstNode> implements Root
|
||||
}
|
||||
|
||||
public List<Issue> getGlobalIssues() {
|
||||
if (multifileAnalysis != null) {
|
||||
return Collections.unmodifiableList(Arrays.asList(multifileAnalysis.getFileIssues(getAstInfo().getFileName())));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return multifileAnalysis.getFileIssues(getAstInfo().getFileName());
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.ast;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.apex.ApexJorjeLogging;
|
||||
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileAnalysis;
|
||||
@@ -45,7 +43,7 @@ public final class ApexParser implements Parser {
|
||||
}
|
||||
|
||||
String property = task.getProperties().getProperty(MULTIFILE_DIRECTORY);
|
||||
@Nullable ApexMultifileAnalysis analysisHandler = ApexMultifileAnalysis.getAnalysisInstance(property);
|
||||
ApexMultifileAnalysis analysisHandler = ApexMultifileAnalysis.getAnalysisInstance(property);
|
||||
|
||||
SourceCodePositioner positioner = new SourceCodePositioner(sourceCode);
|
||||
final ApexTreeBuilder treeBuilder = new ApexTreeBuilder(sourceCode, task.getCommentMarker(), positioner);
|
||||
|
||||
+72
-21
@@ -4,11 +4,19 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.multifile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexParser;
|
||||
|
||||
import com.nawforce.common.api.FileIssueOptions;
|
||||
import com.nawforce.common.api.Org;
|
||||
@@ -27,54 +35,97 @@ import com.nawforce.common.diagnostics.Issue;
|
||||
*/
|
||||
@Experimental
|
||||
public final class ApexMultifileAnalysis {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ApexMultifileAnalysis.class.getName());
|
||||
|
||||
private static Map<String, ApexMultifileAnalysis> instanceMap = new HashMap<>();
|
||||
/**
|
||||
* Instances of the apexlink index and data structures ({@link Org})
|
||||
* are stored statically for now. TODO make that language-wide (#2518).
|
||||
*/
|
||||
private static final Map<String, ApexMultifileAnalysis> INSTANCE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
// An arbitrary large number of errors to report
|
||||
private static final Integer MAX_ERRORS_PER_FILE = 100;
|
||||
|
||||
// Create a new org for each analysis
|
||||
private Org org = Org.newOrg();
|
||||
private FileIssueOptions options = new FileIssueOptions();
|
||||
// Null if failed.
|
||||
private final @Nullable Org org;
|
||||
private final FileIssueOptions options = makeOptions();
|
||||
|
||||
private static final ApexMultifileAnalysis FAILED_INSTANCE = new ApexMultifileAnalysis();
|
||||
|
||||
/** Ctor for the failed instance. */
|
||||
private ApexMultifileAnalysis() {
|
||||
org = null;
|
||||
}
|
||||
|
||||
private ApexMultifileAnalysis(String multiFileAnalysisDirectory) {
|
||||
LOG.fine("MultiFile Analysis created for " + multiFileAnalysisDirectory);
|
||||
org = Org.newOrg();
|
||||
if (multiFileAnalysisDirectory != null && !multiFileAnalysisDirectory.isEmpty()) {
|
||||
// Default issue options, zombies gets us unused methods & fields as well as deploy problems
|
||||
options.includeZombies_$eq(true);
|
||||
options.maxErrorsPerFile_$eq(MAX_ERRORS_PER_FILE);
|
||||
|
||||
// Load the package into the org, this can take some time!
|
||||
org.newSFDXPackage(multiFileAnalysisDirectory);
|
||||
org.newSFDXPackage(multiFileAnalysisDirectory); // this may fail if the config is wrong
|
||||
org.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public Issue[] getFileIssues(String filename) {
|
||||
// Extract issues for a specific metadata file from the org
|
||||
return org.getFileIssues(filename, options);
|
||||
private static FileIssueOptions makeOptions() {
|
||||
FileIssueOptions options = new FileIssueOptions();
|
||||
// Default issue options, zombies gets us unused methods & fields as well as deploy problems
|
||||
options.includeZombies_$eq(true);
|
||||
options.maxErrorsPerFile_$eq(MAX_ERRORS_PER_FILE);
|
||||
return options;
|
||||
}
|
||||
|
||||
public static ApexMultifileAnalysis getAnalysisInstance(String multiFileAnalysisDirectory) {
|
||||
if (instanceMap.isEmpty()) {
|
||||
/**
|
||||
* Returns true if this is analysis index is in a failed state.
|
||||
* This object is then useless. The failed instance is returned
|
||||
* from {@link #getAnalysisInstance(String)} if loading the org
|
||||
* failed, maybe because of malformed configuration.
|
||||
*/
|
||||
public boolean isFailed() {
|
||||
return org == null;
|
||||
}
|
||||
|
||||
public List<Issue> getFileIssues(String filename) {
|
||||
// Extract issues for a specific metadata file from the org
|
||||
return org == null ? Collections.emptyList()
|
||||
: Collections.unmodifiableList(Arrays.asList(org.getFileIssues(filename, options)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analysis instance. Returns a {@linkplain #isFailed() failed instance}
|
||||
* if this fails.
|
||||
*
|
||||
* @param multiFileAnalysisDirectory Root directory of the configuration (see {@link ApexParser#MULTIFILE_DIRECTORY}).
|
||||
*/
|
||||
public static @NonNull ApexMultifileAnalysis getAnalysisInstance(String multiFileAnalysisDirectory) {
|
||||
if (INSTANCE_MAP.isEmpty()) {
|
||||
// Default some library wide settings
|
||||
ServerOps.setAutoFlush(false);
|
||||
ServerOps.setLogger(new AnalysisLogger());
|
||||
ServerOps.setDebugLogging(new String[] {"ALL"});
|
||||
ServerOps.setDebugLogging(new String[] { "ALL" });
|
||||
}
|
||||
|
||||
return instanceMap.computeIfAbsent(multiFileAnalysisDirectory, ApexMultifileAnalysis::create);
|
||||
}
|
||||
|
||||
private static ApexMultifileAnalysis create(String multiFileAnalysisDirectory) {
|
||||
return new ApexMultifileAnalysis(multiFileAnalysisDirectory);
|
||||
return INSTANCE_MAP.computeIfAbsent(
|
||||
multiFileAnalysisDirectory,
|
||||
dir -> {
|
||||
try {
|
||||
return new ApexMultifileAnalysis(dir);
|
||||
} catch (Exception e) {
|
||||
LOG.severe("Exception while initializing Apexlink (" + e.getMessage() + ")");
|
||||
LOG.severe(ExceptionUtils.getStackTrace(e));
|
||||
LOG.severe("PMD will not attempt to initialize Apexlink further, this can cause rules like AvoidUnusedMethod to be dysfunctional");
|
||||
return FAILED_INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Very simple logger to aid debugging, relays ApexLink logging into PMD
|
||||
*/
|
||||
private static class AnalysisLogger implements com.nawforce.common.api.Logger {
|
||||
private static final class AnalysisLogger implements com.nawforce.common.api.Logger {
|
||||
|
||||
@Override
|
||||
public void error(String message) {
|
||||
LOG.fine(message);
|
||||
|
||||
Reference in new issue
Block a user