Skip to content

Commit

Permalink
feat: Add an Source filter to check if errors come from subset of files
Browse files Browse the repository at this point in the history
  • Loading branch information
lqiu96 committed Dec 13, 2024
1 parent bfdf612 commit e380975
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.Queue;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.FieldOrMethod;
Expand All @@ -54,6 +55,7 @@ public class LinkageChecker {
private final ImmutableList<ClassPathEntry> classPath;
private final SymbolReferences symbolReferences;
private final ClassReferenceGraph classReferenceGraph;
private final Artifact sourceFilter;
private final ExcludedErrors excludedErrors;

@VisibleForTesting
Expand All @@ -66,7 +68,7 @@ public ClassReferenceGraph getClassReferenceGraph() {
}

public static LinkageChecker create(List<ClassPathEntry> classPath) throws IOException {
return create(classPath, ImmutableSet.copyOf(classPath), null);
return create(classPath, ImmutableSet.copyOf(classPath), null, null);
}

/**
Expand All @@ -79,6 +81,7 @@ public static LinkageChecker create(List<ClassPathEntry> classPath) throws IOExc
public static LinkageChecker create(
List<ClassPathEntry> classPath,
Iterable<ClassPathEntry> entryPoints,
Artifact sourceFilter,
@Nullable Path exclusionFile)
throws IOException {
Preconditions.checkArgument(!classPath.isEmpty(), "The linkage classpath is empty.");
Expand All @@ -93,6 +96,7 @@ public static LinkageChecker create(
classPath,
symbolReferenceMaps,
classReferenceGraph,
sourceFilter,
ExcludedErrors.create(exclusionFile));
}

Expand Down Expand Up @@ -129,25 +133,27 @@ public static LinkageChecker create(Bom bom, Path exclusionFile)
List<ClassPathEntry> artifactsInBom = classpath.subList(0, managedDependencies.size());
ImmutableSet<ClassPathEntry> entryPoints = ImmutableSet.copyOf(artifactsInBom);

return LinkageChecker.create(classpath, entryPoints, exclusionFile);
return LinkageChecker.create(classpath, entryPoints, null, exclusionFile);
}

@VisibleForTesting
LinkageChecker cloneWith(SymbolReferences newSymbolMaps) {
return new LinkageChecker(
classDumper, classPath, newSymbolMaps, classReferenceGraph, excludedErrors);
classDumper, classPath, newSymbolMaps, classReferenceGraph, null, excludedErrors);
}

private LinkageChecker(
ClassDumper classDumper,
List<ClassPathEntry> classPath,
SymbolReferences symbolReferenceMaps,
ClassReferenceGraph classReferenceGraph,
Artifact sourceFilter,
ExcludedErrors excludedErrors) {
this.classDumper = Preconditions.checkNotNull(classDumper);
this.classPath = ImmutableList.copyOf(classPath);
this.classReferenceGraph = Preconditions.checkNotNull(classReferenceGraph);
this.symbolReferences = Preconditions.checkNotNull(symbolReferenceMaps);
this.sourceFilter = sourceFilter;
this.excludedErrors = Preconditions.checkNotNull(excludedErrors);
}

Expand All @@ -161,7 +167,13 @@ public ImmutableSet<LinkageProblem> findLinkageProblems() throws IOException {
ImmutableSet.Builder<LinkageProblem> problemToClass = ImmutableSet.builder();

// This sourceClassFile is a source of references to other symbols.
for (ClassFile classFile : symbolReferences.getClassFiles()) {
Set<ClassFile> classFiles = symbolReferences.getClassFiles();
if (sourceFilter != null) {
classFiles = classFiles.stream()
.filter(x -> x.getClassPathEntry().getArtifact().toString().equals(sourceFilter.toString()))
.collect(Collectors.toSet());
}
for (ClassFile classFile : classFiles) {
ImmutableSet<ClassSymbol> classSymbols = symbolReferences.getClassSymbols(classFile);
for (ClassSymbol classSymbol : classSymbols) {
if (classSymbol instanceof SuperClassSymbol) {
Expand Down Expand Up @@ -202,7 +214,7 @@ public ImmutableSet<LinkageProblem> findLinkageProblems() throws IOException {
}
}

for (ClassFile classFile : symbolReferences.getClassFiles()) {
for (ClassFile classFile : classFiles) {
ImmutableSet<MethodSymbol> methodSymbols = symbolReferences.getMethodSymbols(classFile);
ImmutableSet<String> classFileNames = classFile.getClassPathEntry().getFileNames();
for (MethodSymbol methodSymbol : methodSymbols) {
Expand All @@ -215,7 +227,7 @@ public ImmutableSet<LinkageProblem> findLinkageProblems() throws IOException {
}
}

for (ClassFile classFile : symbolReferences.getClassFiles()) {
for (ClassFile classFile : classFiles) {
ImmutableSet<FieldSymbol> fieldSymbols = symbolReferences.getFieldSymbols(classFile);
ImmutableSet<String> classFileNames = classFile.getClassPathEntry().getFileNames();
for (FieldSymbol fieldSymbol : fieldSymbols) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
Expand Down Expand Up @@ -124,6 +126,14 @@ private static Options configureOptions() {
.build();
inputGroup.addOption(jarOption);

Option sourceFilter =
Option.builder("s")
.longOpt("source-filter")
.hasArg(true)
.desc("Source Filter")
.build();
options.addOption(sourceFilter);

Option repositoryOption =
Option.builder("m")
.longOpt("maven-repositories")
Expand Down Expand Up @@ -277,4 +287,12 @@ Path getOutputExclusionFile() {
}
return null;
}

Artifact getSourceFilterArtifact() {
if (commandLine.hasOption("s")) {
String mavenCoordinatesOption = commandLine.getOptionValue('s');
return new DefaultArtifact(mavenCoordinatesOption);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private static Problems checkJarFiles(
ImmutableSet<ClassPathEntry> entryPoints = ImmutableSet.copyOf(inputClassPath);
LinkageChecker linkageChecker =
LinkageChecker.create(
inputClassPath, entryPoints, linkageCheckerArguments.getInputExclusionFile());
inputClassPath, entryPoints, null, linkageCheckerArguments.getInputExclusionFile());

ImmutableSet<LinkageProblem> linkageProblems =
findLinkageProblems(linkageChecker, linkageCheckerArguments.getReportOnlyReachable());
Expand Down Expand Up @@ -161,7 +161,7 @@ private static Problems checkArtifacts(

LinkageChecker linkageChecker =
LinkageChecker.create(
inputClassPath, entryPoints, linkageCheckerArguments.getInputExclusionFile());
inputClassPath, entryPoints, linkageCheckerArguments.getSourceFilterArtifact(), linkageCheckerArguments.getInputExclusionFile());
ImmutableSet<LinkageProblem> linkageProblems =
findLinkageProblems(linkageChecker,
linkageCheckerArguments.getReportOnlyReachable());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public void execute() throws EnforcerRuleException {
// findLinkageProblems immediately after create.

Path exclusionFile = this.exclusionFile == null ? null : Paths.get(this.exclusionFile);
LinkageChecker linkageChecker = LinkageChecker.create(classPath, entryPoints, exclusionFile);
LinkageChecker linkageChecker = LinkageChecker.create(classPath, entryPoints, null, exclusionFile);
ImmutableSet<LinkageProblem> linkageProblems = linkageChecker.findLinkageProblems();
if (reportOnlyReachable) {
ClassReferenceGraph classReferenceGraph = linkageChecker.getClassReferenceGraph();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ private ImmutableSet<LinkageProblem> run(String groupId, String artifactId)
List<ClassPathEntry> entryPointJars = classpath.subList(0, snapshotManagedDependencies.size());

ImmutableSet<LinkageProblem> problemsInSnapshot =
LinkageChecker.create(classpath, ImmutableSet.copyOf(entryPointJars), null)
LinkageChecker.create(classpath, ImmutableSet.copyOf(entryPointJars), null, null)
.findLinkageProblems();

if (problemsInBaseline.equals(problemsInSnapshot)) {
Expand Down

0 comments on commit e380975

Please sign in to comment.