Skip to content
Open
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 @@ -9,12 +9,14 @@

import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Status;

import com.salesforce.bazel.sdk.command.querylight.Target;
import com.salesforce.bazel.sdk.model.BazelLabel;

/**
Expand Down Expand Up @@ -71,6 +73,7 @@ public static boolean isBuildFileName(String fileName) {
private final BazelWorkspace parent;
private final BazelLabel label;
private final IPath packagePath;
private Map<String, Target> targets;

BazelPackage(BazelWorkspace parent, IPath packagePath) throws NullPointerException, IllegalArgumentException {
this.packagePath =
Expand All @@ -87,7 +90,9 @@ protected BazelPackageInfo createInfo() throws CoreException {
Status.error(format("Package '%s' does not exist in workspace '%s'!", label, parent.getName())));
}

var targets = BazelPackageInfo.queryForTargets(this, getCommandExecutor());
if (targets == null) {
targets = BazelPackageInfo.queryForTargets(this, getCommandExecutor());
}
return new BazelPackageInfo(buildFile, this, targets);
}

Expand Down Expand Up @@ -344,4 +349,8 @@ public void rediscoverBazelProject() throws CoreException {
getInfo();
}

public void setTargets(Map<String, Target> targets) {
this.targets = targets;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_REPO_BAZEL;
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_WORKSPACE;
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_WORKSPACE_BAZEL;
import static com.salesforce.bazel.eclipse.core.model.BazelPackageInfo.queryForTargets;
import static java.lang.String.format;
import static java.nio.file.Files.isDirectory;
import static java.nio.file.Files.isRegularFile;
import static java.util.Objects.requireNonNull;
import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
Expand All @@ -43,6 +45,8 @@
import com.salesforce.bazel.eclipse.core.projectview.BazelProjectView;
import com.salesforce.bazel.sdk.BazelVersion;
import com.salesforce.bazel.sdk.command.BazelBinary;
import com.salesforce.bazel.sdk.command.BazelQueryForTargetProtoCommand;
import com.salesforce.bazel.sdk.command.querylight.Target;
import com.salesforce.bazel.sdk.model.BazelLabel;

/**
Expand Down Expand Up @@ -616,7 +620,7 @@ public void open(Collection<BazelPackage> bazelPackages) throws CoreException {
}

// open all closed projects
var targetsByPackage = queryForTargets(this, closedPackages, getCommandExecutor());
var targetsByPackage = queryForTargetsWithDependencies(this, closedPackages, getCommandExecutor());
for (BazelPackage bazelPackage : closedPackages) {
if (bazelPackage.hasInfo()) {
continue;
Expand Down Expand Up @@ -644,6 +648,75 @@ public void open(Collection<BazelPackage> bazelPackages) throws CoreException {
}
}

public Map<BazelPackage, Map<String, Target>> queryForTargetsWithDependencies(BazelWorkspace bazelWorkspace,
Collection<BazelPackage> bazelPackages, BazelElementCommandExecutor bazelElementCommandExecutor)
throws CoreException {
// bazel query 'kind(rule, deps(//foo:all + //bar:all))"'

if (bazelPackages.isEmpty()) {
return Collections.emptyMap();
}
var workspaceRoot = bazelWorkspace.getLocation().toPath();
var query = bazelPackages.stream()
.map(bazelPackage -> format("//%s:all", bazelPackage.getWorkspaceRelativePath()))
.collect(joining(" + "));

Map<String, BazelPackage> bazelPackageByWorkspaceRelativePath = new HashMap<>();
bazelPackages.stream()
.forEach(p -> bazelPackageByWorkspaceRelativePath.put(p.getWorkspaceRelativePath().toString(), p));

query = "kind(rule, deps(" + query + "))";
Map<BazelPackage, Map<String, Target>> result = new HashMap<>();
LOG.debug("{}: querying Bazel for list of targets from: {}", bazelWorkspace, query);
var queryResult = bazelElementCommandExecutor.runQueryWithoutLock(
new BazelQueryForTargetProtoCommand(
workspaceRoot,
query,
true /* keep going */,
List.of("--noproto:locations", "--noproto:default_values", "--noimplicit_deps", "--notool_deps"),
format(
"Loading targets for %d %s",
bazelPackages.size(),
bazelPackages.size() == 1 ? "package" : "packages")));
for (Target target : queryResult) {
if (!target.hasRule()) {
LOG.trace("{}: ignoring target: {}", bazelWorkspace, target);
System.out.println();
continue;
}

try {
BazelLabel.validateLabelPath(target.rule().name(), true);
} catch (Exception e) {
LOG.trace("{}: ignoring target: {}", bazelWorkspace, target);
continue;
}
LOG.trace("{}: found target: {}", bazelWorkspace, target);
var targetLabel = new BazelLabel(target.rule().name());

var bazelPackage = bazelPackageByWorkspaceRelativePath.get(targetLabel.getPackagePath());
if (bazelPackage == null) {
// LOG.debug("{}: ignoring target for unknown package: {}", bazelWorkspace, targetLabel);
// continue;
var packageLabel = targetLabel.getPackageLabel();
if (bazelWorkspace.isRootedAtThisWorkspace(packageLabel)) {
bazelPackage = bazelWorkspace.getBazelPackage(packageLabel);
}
}
if (bazelPackage == null) {
LOG.debug("{}: ignoring target for unknown package: {}", bazelWorkspace, targetLabel);
continue;
}
if (!result.containsKey(bazelPackage)) {
result.put(bazelPackage, new HashMap<>());
}

var targetName = targetLabel.getTargetName();
result.get(bazelPackage).put(targetName, target);
}
return result;
}

Path workspacePath() {
return root.toPath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.google.idea.blaze.base.model.primitives.TargetName;
import com.salesforce.bazel.eclipse.core.classpath.BazelClasspathScope;
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath;
import com.salesforce.bazel.eclipse.core.model.BazelPackage;
import com.salesforce.bazel.eclipse.core.model.BazelProject;
import com.salesforce.bazel.eclipse.core.model.BazelTarget;
import com.salesforce.bazel.eclipse.core.model.BazelWorkspace;
Expand Down Expand Up @@ -158,6 +159,7 @@ protected List<BazelProject> doProvisionProjects(Collection<TargetExpression> ta

monitor.beginTask("Provisioning projects", packages.size() * 3);
var result = new ArrayList<BazelProject>();
var bazelPackages = new ArrayList<BazelPackage>();
for (Path packagePath : packages) {
var bazelPackage = workspace.getBazelPackage(IPath.fromPath(packagePath));

Expand All @@ -171,6 +173,13 @@ protected List<BazelProject> doProvisionProjects(Collection<TargetExpression> ta
STRATEGY_NAME)));
continue;
}
bazelPackages.add(bazelPackage);
}
var targetsByPackage =
workspace.queryForTargetsWithDependencies(workspace, bazelPackages, workspace.getCommandExecutor());

for (BazelPackage bazelPackage : bazelPackages) {
bazelPackage.setTargets(targetsByPackage.get(bazelPackage));

// get the top-level macro calls
var topLevelMacroCalls = bazelPackage.getBazelBuildFile().getTopLevelCalls();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IWorkspaceRoot;
Expand Down Expand Up @@ -61,13 +62,15 @@
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath;
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath.Builder;
import com.salesforce.bazel.eclipse.core.model.BazelPackage;
import com.salesforce.bazel.eclipse.core.model.BazelProject;
import com.salesforce.bazel.eclipse.core.model.BazelTarget;
import com.salesforce.bazel.eclipse.core.model.BazelWorkspace;
import com.salesforce.bazel.eclipse.core.model.discovery.classpath.AccessRule;
import com.salesforce.bazel.eclipse.core.model.discovery.classpath.ClasspathEntry;
import com.salesforce.bazel.sdk.command.BazelBuildWithIntelliJAspectsCommand;
import com.salesforce.bazel.sdk.command.querylight.BazelRuleAttribute;
import com.salesforce.bazel.sdk.command.querylight.Target;
import com.salesforce.bazel.sdk.model.BazelLabel;

/**
Expand Down Expand Up @@ -331,6 +334,11 @@ public IStatus addTarget(BazelTarget bazelTarget) throws CoreException {
* @throws CoreException
*/
public CompileAndRuntimeClasspath compute() throws CoreException {
return compute(null);
}

public CompileAndRuntimeClasspath compute(Map<BazelPackage, Map<String, Target>> targetsByPackage)
throws CoreException {
// the code below is copied and adapted from BlazeJavaWorkspaceImporter

var classpathBuilder = new Builder();
Expand Down Expand Up @@ -359,7 +367,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {
var targetKey = targetLabel != null ? TargetKey.forPlainTarget(targetLabel) : null;
library = new BlazeJarLibrary(libraryArtifact, targetKey);
}
var entry = resolveLibrary(library);
var entry = resolveLibrary(library, targetsByPackage);
if (entry != null) {
if (!validateEntry(entry)) {
continue;
Expand Down Expand Up @@ -400,7 +408,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {

// Collect jars referenced by direct deps
for (TargetKey targetKey : directDeps) {
var entries = resolveDependency(targetKey);
var entries = resolveDependency(targetKey, targetsByPackage);
for (ClasspathEntry entry : entries) {
if (validateEntry(entry)) {
classpathBuilder.addCompileEntry(entry);
Expand All @@ -410,7 +418,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {

// Collect jars referenced by runtime deps
for (TargetKey targetKey : runtimeDeps) {
var entries = resolveDependency(targetKey);
var entries = resolveDependency(targetKey, targetsByPackage);
var addRuntimeDependencyAsCompileEntry = includeRuntimeDependencyAsProjectCompileDependency(targetKey);

for (ClasspathEntry entry : entries) {
Expand Down Expand Up @@ -585,8 +593,9 @@ protected boolean relevantDep(Deps.Dependency dep) {
return (dep.getKind() == Deps.Dependency.Kind.EXPLICIT) || (dep.getKind() == Deps.Dependency.Kind.IMPLICIT);
}

protected Collection<ClasspathEntry> resolveDependency(TargetKey targetKey) throws CoreException {
var projectEntry = resolveProject(targetKey);
protected Collection<ClasspathEntry> resolveDependency(TargetKey targetKey,
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
var projectEntry = resolveProject(targetKey, targetsByPackage);
if (projectEntry != null) {
return Set.of(projectEntry);
}
Expand Down Expand Up @@ -623,10 +632,11 @@ protected BlazeArtifact resolveJdepsOutput(TargetIdeInfo target) {
return locationDecoder.resolveOutput(javaIdeInfo.getJdepsFile());
}

private ClasspathEntry resolveLibrary(BlazeJarLibrary library) throws CoreException {
private ClasspathEntry resolveLibrary(BlazeJarLibrary library,
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
// find project in workspace if possible
if (library.targetKey != null) {
var projectEntry = resolveProject(library.targetKey);
var projectEntry = resolveProject(library.targetKey, targetsByPackage);
if (projectEntry != null) {
return projectEntry;
}
Expand All @@ -636,7 +646,8 @@ private ClasspathEntry resolveLibrary(BlazeJarLibrary library) throws CoreExcept
return resolveJar(library.libraryArtifact);
}

private ClasspathEntry resolveProject(final Label targetLabel) throws CoreException {
private ClasspathEntry resolveProject(final Label targetLabel,
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
var workspace = bazelWorkspace;

// check for project mapping (it trumps everything)
Expand Down Expand Up @@ -686,10 +697,18 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
}
}
var bazelPackage = workspace.getBazelPackage(forPosix(targetLabel.blazePackage().relativePath()));
var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
if (bazelTarget.hasBazelProject() && bazelTarget.getBazelProject().getProject().isAccessible()) {
// a direct target match is preferred
return newProjectReference(targetLabel, bazelTarget.getBazelProject());
if (targetsByPackage != null) {
var targets = targetsByPackage.get(bazelPackage);
bazelPackage.setTargets(targets);
}
var strategy = new TargetDiscoveryAndProvisioningExtensionLookup()
.createTargetProvisioningStrategy(bazelWorkspace.getBazelProjectView());
if (strategy instanceof ProjectPerTargetProvisioningStrategy) {
var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
if (bazelTarget.hasBazelProject() && bazelTarget.getBazelProject().getProject().isAccessible()) {
// a direct target match is preferred
return newProjectReference(targetLabel, bazelTarget.getBazelProject());
}
}
if (bazelPackage.hasBazelProject() && bazelPackage.getBazelProject().getProject().isAccessible()) {
// we have to check the target name is part of the enabled project list
Expand All @@ -701,7 +720,7 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
.anyMatch(t -> t.getTargetName().equals(targetName))) {
return newProjectReference(targetLabel, bazelPackage.getBazelProject());
}

var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
// it may be possible that the target is explicitly hidden from IDEs
// in this case, it won't match in the above condition, however, we still want to make it a project references
// the reason is that we do expect the project to represent the package adequately
Expand All @@ -715,12 +734,13 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
return null;
}

protected ClasspathEntry resolveProject(TargetKey targetKey) throws CoreException {
protected ClasspathEntry resolveProject(TargetKey targetKey,
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
if (!targetKey.isPlainTarget()) {
return null;
}

return resolveProject(targetKey.getLabel());
return resolveProject(targetKey.getLabel(), targetsByPackage);
}

/**
Expand Down
Loading
Loading