Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

[Post BazelBuilder refactor part 1] TargetsResolver update #33

Merged
merged 12 commits into from
Jan 14, 2021
2 changes: 1 addition & 1 deletion src/main/java/org/jetbrains/bsp/bazel/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ java_library(
"//src/main/java/org/jetbrains/bsp/bazel/server/bazel",
"//src/main/java/org/jetbrains/bsp/bazel/server/bazel/data",
"//src/main/java/org/jetbrains/bsp/bazel/server/bep",
"//src/main/java/org/jetbrains/bsp/bazel/server/bep/loggers",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/impl",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/resolvers",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/services",
"//src/main/java/org/jetbrains/bsp/bazel/server/logger",
"@io_bazel//src/main/protobuf:build_java_proto",
"@io_bazel//third_party/grpc:grpc-jar",
"@maven//:ch_epfl_scala_bsp4j",
Expand Down
11 changes: 3 additions & 8 deletions src/main/java/org/jetbrains/bsp/bazel/server/BazelBspServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.jetbrains.bsp.bazel.server.bazel.BazelRunner;
import org.jetbrains.bsp.bazel.server.bazel.data.BazelData;
import org.jetbrains.bsp.bazel.server.bep.BepServer;
import org.jetbrains.bsp.bazel.server.bep.loggers.BuildClientLogger;
import org.jetbrains.bsp.bazel.server.bsp.BazelBspServerBuildManager;
import org.jetbrains.bsp.bazel.server.bsp.BazelBspServerConfig;
import org.jetbrains.bsp.bazel.server.bsp.BazelBspServerLifetime;
Expand All @@ -18,12 +19,9 @@
import org.jetbrains.bsp.bazel.server.bsp.impl.BuildServerImpl;
import org.jetbrains.bsp.bazel.server.bsp.impl.JavaBuildServerImpl;
import org.jetbrains.bsp.bazel.server.bsp.impl.ScalaBuildServerImpl;
import org.jetbrains.bsp.bazel.server.bsp.resolvers.ActionGraphResolver;
import org.jetbrains.bsp.bazel.server.bsp.resolvers.TargetsResolver;
import org.jetbrains.bsp.bazel.server.bsp.services.BuildServerService;
import org.jetbrains.bsp.bazel.server.bsp.services.JavaBuildServerService;
import org.jetbrains.bsp.bazel.server.bsp.services.ScalaBuildServerService;
import org.jetbrains.bsp.bazel.server.logger.BuildClientLogger;

public class BazelBspServer {

Expand All @@ -49,9 +47,6 @@ public void startServer(BspIntegrationData bspIntegrationData) {
BazelBspServerRequestHelpers serverRequestHelpers =
new BazelBspServerRequestHelpers(serverLifetime);

TargetsResolver targetsResolver = new TargetsResolver(bazelRunner);
ActionGraphResolver actionGraphResolver = new ActionGraphResolver(bazelRunner);

this.serverBuildManager =
new BazelBspServerBuildManager(serverConfig, serverRequestHelpers, bazelData, bazelRunner);

Expand All @@ -60,9 +55,9 @@ public void startServer(BspIntegrationData bspIntegrationData) {
serverRequestHelpers, serverLifetime, serverBuildManager, bazelData, bazelRunner);

ScalaBuildServerService scalaBuildServerService =
new ScalaBuildServerService(bazelData, targetsResolver, actionGraphResolver);
new ScalaBuildServerService(bazelData, bazelRunner);
JavaBuildServerService javaBuildServerService =
new JavaBuildServerService(bazelData, targetsResolver, actionGraphResolver);
new JavaBuildServerService(bazelData, bazelRunner);

this.scalaBuildServer = new ScalaBuildServerImpl(scalaBuildServerService, serverRequestHelpers);
this.javaBuildServer = new JavaBuildServerImpl(javaBuildServerService, serverRequestHelpers);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jetbrains/bsp/bazel/server/bep/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ java_library(
"//src/main/java/org/jetbrains/bsp/bazel/commons",
"//src/main/java/org/jetbrains/bsp/bazel/server/bazel/data",
"//src/main/java/org/jetbrains/bsp/bazel/server/bazel/utils",
"//src/main/java/org/jetbrains/bsp/bazel/server/bep/loggers",
"//src/main/java/org/jetbrains/bsp/bazel/server/bep/parsers",
"//src/main/java/org/jetbrains/bsp/bazel/server/bep/parsers/error",
"//src/main/java/org/jetbrains/bsp/bazel/server/logger",
"@com_google_protobuf//:protobuf_java",
"@googleapis//:google_devtools_build_v1_build_events_java_proto",
"@googleapis//:google_devtools_build_v1_publish_build_event_java_grpc",
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/org/jetbrains/bsp/bazel/server/bep/BepServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
import org.jetbrains.bsp.bazel.commons.Uri;
import org.jetbrains.bsp.bazel.server.bazel.data.BazelData;
import org.jetbrains.bsp.bazel.server.bazel.utils.ExitCodeMapper;
import org.jetbrains.bsp.bazel.server.bep.loggers.BuildClientLogger;
import org.jetbrains.bsp.bazel.server.bep.parsers.ClasspathParser;
import org.jetbrains.bsp.bazel.server.bep.parsers.error.StderrDiagnosticsParser;
import org.jetbrains.bsp.bazel.server.logger.BuildClientLogger;

public class BepServer extends PublishBuildEventGrpc.PublishBuildEventImplBase {

Expand Down Expand Up @@ -229,8 +229,12 @@ private void processAbortedEvent(BuildEventStreamProtos.BuildEvent event) {

private void consumeAbortedEvent(BuildEventStreamProtos.Aborted aborted) {
if (aborted.getReason() != BuildEventStreamProtos.Aborted.AbortReason.NO_BUILD) {
buildClientLogger.logError(
"Command aborted with reason " + aborted.getReason() + ": " + aborted.getDescription());
String errorMessage =
String.format(
"Command aborted with reason %s: %s", aborted.getReason(), aborted.getDescription());
buildClientLogger.logError(errorMessage);

throw new RuntimeException(errorMessage);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@rules_java//java:defs.bzl", "java_library")

java_library(
name = "logger",
name = "loggers",
srcs = glob(["*.java"]),
visibility = ["//visibility:public"],
deps = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jetbrains.bsp.bazel.server.logger;
package org.jetbrains.bsp.bazel.server.bep.loggers;

import ch.epfl.scala.bsp4j.BuildClient;
import ch.epfl.scala.bsp4j.LogMessageParams;
Expand All @@ -14,13 +14,15 @@ public BuildClientLogger(BuildClient buildClient) {

public void logError(String errorMessage) {
LogMessageParams params = new LogMessageParams(MessageType.ERROR, errorMessage);
buildClient.onBuildLogMessage(params);
// TODO why this function throws exception?
throw new RuntimeException(errorMessage);
log(params);
}

public void logMessage(String message) {
LogMessageParams params = new LogMessageParams(MessageType.LOG, message);
log(params);
}

private void log(LogMessageParams params) {
buildClient.onBuildLogMessage(params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ java_library(
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/utils",
"@io_bazel//src/main/protobuf:analysis_java_proto",
"@io_bazel//src/main/protobuf:build_java_proto",
"@maven//:ch_epfl_scala_bsp4j",
"@maven//:com_google_guava_guava",
"@maven//:org_eclipse_lsp4j_org_eclipse_lsp4j_jsonrpc",
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,174 @@
package org.jetbrains.bsp.bazel.server.bsp.resolvers;

import ch.epfl.scala.bsp4j.BuildTargetIdentifier;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.bsp.bazel.commons.Constants;
import org.jetbrains.bsp.bazel.commons.Uri;
import org.jetbrains.bsp.bazel.server.bazel.BazelRunner;
import org.jetbrains.bsp.bazel.server.bazel.data.BazelData;
import org.jetbrains.bsp.bazel.server.bazel.data.BazelProcessResult;
import org.jetbrains.bsp.bazel.server.bazel.params.BazelRunnerFlag;

public class TargetsResolver {
public class TargetsResolver<T> {

private static final List<String> ACTION_GRAPH_SUFFIXES = ImmutableList.of(".jar", ".js");
private final BazelData bazelData;
private final BazelRunner bazelRunner;
private final ActionGraphResolver actionGraphResolver;
private final String compilerOptionsName;
private final List<String> languagesIds;
private final ResultItemsCollector<T> resultItemsCollector;

public TargetsResolver(BazelRunner bazelRunner) {
private TargetsResolver(
BazelData bazelData,
BazelRunner bazelRunner,
String compilerOptionsName,
List<String> languagesIds,
ResultItemsCollector<T> resultItemsCollector) {
this.bazelData = bazelData;
this.bazelRunner = bazelRunner;
this.compilerOptionsName = compilerOptionsName;
this.languagesIds = languagesIds;
this.resultItemsCollector = resultItemsCollector;

this.actionGraphResolver = new ActionGraphResolver(bazelRunner);
}

public static <T> Builder<T> builder() {
return new Builder<>();
}

public List<T> getResultItemsForTargets(List<BuildTargetIdentifier> buildTargetsIdentifiers) {
List<String> targets = TargetsUtils.getTargetsUris(buildTargetsIdentifiers);

return targets.stream()
.flatMap(target -> getResultItems(target, targets))
.collect(Collectors.toList());
}

private Stream<T> getResultItems(String target, List<String> allTargets) {
Map<String, List<String>> targetsOptions = getTargetsOptions(allTargets);
ActionGraphParser actionGraphParser =
actionGraphResolver.getActionGraphParser(allTargets, languagesIds);

return getResultItemForActionGraphParserOptionsTargetsOptionsAndTarget(
actionGraphParser, targetsOptions, target);
}

public Map<String, List<String>> getTargetsOptions(
List<String> targets, String compilerOptionsName) {
BazelProcessResult bazelProcessResult =
bazelRunner
.commandBuilder()
.query()
.withFlag(BazelRunnerFlag.OUTPUT_PROTO)
.withTargets(targets)
.executeBazelCommand();
private Map<String, List<String>> getTargetsOptions(List<String> targets) {
BazelProcessResult bazelProcessResult = queryBazel(targets);

Build.QueryResult query = QueryResolver.getQueryResultForProcess(bazelProcessResult);

return query.getTargetList().stream()
.map(Build.Target::getRule)
.collect(
Collectors.toMap(
Build.Rule::getName,
(rule) ->
rule.getAttributeList().stream()
.filter(attr -> attr.getName().equals(compilerOptionsName))
.flatMap(attr -> attr.getStringListValueList().stream())
.collect(Collectors.toList())));
.collect(Collectors.toMap(Build.Rule::getName, this::collectRules));
}

private BazelProcessResult queryBazel(List<String> targets) {
return bazelRunner
.commandBuilder()
.query()
.withFlag(BazelRunnerFlag.OUTPUT_PROTO)
.withTargets(targets)
.executeBazelCommand();
}

private List<String> collectRules(Build.Rule rule) {
return rule.getAttributeList().stream()
.filter(this::isAttributeCompilerOptionsName)
.flatMap(attr -> attr.getStringListValueList().stream())
.collect(Collectors.toList());
}

private boolean isAttributeCompilerOptionsName(Build.Attribute attribute) {
return attribute.getName().equals(compilerOptionsName);
}

private Stream<T> getResultItemForActionGraphParserOptionsTargetsOptionsAndTarget(
ActionGraphParser actionGraphParser,
Map<String, List<String>> targetsOptions,
String target) {

BuildTargetIdentifier targetIdentifier = new BuildTargetIdentifier(target);
List<String> options = targetsOptions.getOrDefault(target, ImmutableList.of());
List<String> inputs = actionGraphParser.getInputsAsUri(target, bazelData.getExecRoot());

return actionGraphParser.getOutputs(target, ACTION_GRAPH_SUFFIXES).stream()
.map(this::mapActionGraphOutputsToClassDirectory)
.map(
classDirectory ->
resultItemsCollector.apply(targetIdentifier, options, inputs, classDirectory));
}

private String mapActionGraphOutputsToClassDirectory(String output) {
String execPath = Constants.EXEC_ROOT_PREFIX + output;

return Uri.fromExecPath(execPath, bazelData.getExecRoot()).toString();
}

@FunctionalInterface
public interface ResultItemsCollector<T> {
T apply(
BuildTargetIdentifier target,
List<String> options,
List<String> classpath,
String classDirectory);
}

public static class Builder<T> {
SocksDevil marked this conversation as resolved.
Show resolved Hide resolved

private BazelData bazelData;
private BazelRunner bazelRunner;
private String compilerOptionsName;
private List<String> languagesIds;
private ResultItemsCollector<T> resultItemsCollector;

public Builder<T> bazelData(BazelData bazelData) {
this.bazelData = bazelData;
return this;
}

public Builder<T> bazelRunner(BazelRunner bazelRunner) {
this.bazelRunner = bazelRunner;
return this;
}

public Builder<T> compilerOptionsName(String compilerOptionsName) {
this.compilerOptionsName = compilerOptionsName;
return this;
}

public Builder<T> languagesIds(List<String> languagesIds) {
this.languagesIds = languagesIds;
return this;
}

public Builder<T> resultItemsCollector(ResultItemsCollector<T> resultItemsCollector) {
this.resultItemsCollector = resultItemsCollector;
return this;
}

public TargetsResolver<T> build() {
throwExceptionIfAnyFieldIsNotFilled();

return new TargetsResolver<T>(
bazelData, bazelRunner, compilerOptionsName, languagesIds, resultItemsCollector);
}

private void throwExceptionIfAnyFieldIsNotFilled() {
if (bazelData == null
|| bazelRunner == null
|| compilerOptionsName == null
|| languagesIds == null
|| resultItemsCollector == null) {
throw new IllegalStateException("Every TargetsResolver.Builder field has to be set");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.jetbrains.bsp.bazel.server.bsp.resolvers;

import ch.epfl.scala.bsp4j.BuildTargetIdentifier;
import java.util.List;
import java.util.stream.Collectors;

public final class TargetsUtils {

public static List<String> getTargetsUris(List<BuildTargetIdentifier> targets) {
return targets.stream().map(BuildTargetIdentifier::getUri).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ java_library(
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/resolvers",
"//src/main/java/org/jetbrains/bsp/bazel/server/bsp/utils",
"//src/main/java/org/jetbrains/bsp/bazel/server/logger",
"@io_bazel//src/main/protobuf:build_java_proto",
"@io_bazel//third_party/grpc:grpc-jar",
"@maven//:ch_epfl_scala_bsp4j",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.jetbrains.bsp.bazel.server.bsp.BazelBspServerLifetime;
import org.jetbrains.bsp.bazel.server.bsp.BazelBspServerRequestHelpers;
import org.jetbrains.bsp.bazel.server.bsp.resolvers.QueryResolver;
import org.jetbrains.bsp.bazel.server.bsp.resolvers.TargetsUtils;

public class BuildServerService {

Expand Down Expand Up @@ -135,10 +136,7 @@ public CompletableFuture<WorkspaceBuildTargetsResult> workspaceBuildTargets() {
}

public Either<ResponseError, SourcesResult> buildTargetSources(SourcesParams sourcesParams) {
List<String> targets =
sourcesParams.getTargets().stream()
.map(BuildTargetIdentifier::getUri)
.collect(Collectors.toList());
List<String> targets = TargetsUtils.getTargetsUris(sourcesParams.getTargets());

BazelProcessResult bazelProcessResult =
bazelRunner
Expand Down Expand Up @@ -204,10 +202,7 @@ public Either<ResponseError, InverseSourcesResult> buildTargetInverseSources(

public Either<ResponseError, DependencySourcesResult> buildTargetDependencySources(
DependencySourcesParams dependencySourcesParams) {
List<String> targets =
dependencySourcesParams.getTargets().stream()
.map(BuildTargetIdentifier::getUri)
.collect(Collectors.toList());
List<String> targets = TargetsUtils.getTargetsUris(dependencySourcesParams.getTargets());

DependencySourcesResult result =
new DependencySourcesResult(
Expand Down Expand Up @@ -285,10 +280,7 @@ public Either<ResponseError, TestResult> buildTargetTest(TestParams testParams)
return Either.forRight(new TestResult(result.getStatusCode()));
}

List<String> testTargets =
testParams.getTargets().stream()
.map(BuildTargetIdentifier::getUri)
.collect(Collectors.toList());
List<String> testTargets = TargetsUtils.getTargetsUris(testParams.getTargets());

BazelProcessResult bazelProcessResult =
bazelRunner
Expand Down
Loading