Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select source roots for library jars that have interim folders like `… #5117

Merged

Conversation

dkashyn-sfdc
Copy link
Contributor

@dkashyn-sfdc dkashyn-sfdc commented Jul 17, 2023

…/src/...`. IJ UI logic is reused and suggested candidate selected if and only if there is one candidate exists.

Checklist

  • I have filed an issue about this change and discussed potential changes with the maintainers.
  • I have received the approval from the maintainers to make this change.
  • This is not a stylistic, refactoring, or cleanup change.

Please note that the maintainers will not be reviewing this change until all checkboxes are ticked. See
the Contributions section in the README for more
details.

Discussion thread for this change

Issue number: <please reference the issue number or url here>

Description of this change

…/src/...`. IJ UI logic is reused and suggested candidate selected if and only if there is one candidate exists.
@google-cla
Copy link

google-cla bot commented Jul 17, 2023

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@Pavank1992 Pavank1992 added the awaiting-review Awaiting review from Bazel team on PRs label Jul 18, 2023
@tpasternak
Copy link
Collaborator

tpasternak commented Jul 19, 2023

So finally I managed to reproduce this issue, here's the minimal repro

SCENARIO:

  1. Import the project below with x.projectview
  2. Open Main.java
  3. Try to go to Library definition from there

Instead of jumping to //lib:lib's src jar, IntelliJ jumps to decompiled code, because the liblib-src.jar has been attached in the wrong way

──────────────────────────────────────────────────────────────────────────────────────
File: lib/BUILD
──────────────────────────────────────────────────────────────────────────────────────
java_library(
    name = "lib",
    srcs = glob(["java/**/*.java"]),
    visibility = ["//visibility:public"],
)
──────────────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────────────
File: lib/java/src/org/example/Library.java
──────────────────────────────────────────────────────────────────────────────────────
package org.example;

public class Library {

}
──────────────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────────────
File: src/BUILD
──────────────────────────────────────────────────────────────────────────────────────
java_binary(
    name = "binary",
    srcs = ["Main.java"],
    main_class = "Main",
    deps = [
        "//lib",
    ],
)
──────────────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────────────
File: src/Main.java
──────────────────────────────────────────────────────────────────────────────────────
import org.example.Library;

class Main {

    Library l;
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}
──────────────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────────────
File: x.bazelproject
──────────────────────────────────────────────────────────────────────────────────────
directories:
  src

derive_targets_from_directories: false

targets:
  //src/...
──────────────────────────────────────────────────────────────────────────────────────

@tpasternak
Copy link
Collaborator

This could be related to these long-outstanding issues
#1206
#1207
bazelbuild/bazel#8277

@@ -73,7 +79,20 @@ private void addRoot(File file, OrderRootType orderRootType) {
logger.warn("No local file found for " + file);
return;
}
modifiableModel.addRoot(pathToUrl(file), orderRootType);
if (Registry.is("bazel.sync.detect.source.roots") && orderRootType == OrderRootType.SOURCES) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but maybe Instead of doing it in LibraryModifier.addRoots, which is called in a lot of contexts, we could create a new method here? This method could be then called by BlazeAttachSourceProvider.attachSources instead of LibraryEditor.updateLibrary.

In this way, we could ensure that the scanning is not performed anywhere else except on-demand source attachment task.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is that, the JavaVfsSourceRootDetectionUtil.suggestRoots call can be quite havy - it recursively scans the whole jar. https://github.com/JetBrains/intellij-community/blob/d0750485a3e0fd0123b8388478a41010c9c329ce/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaVfsSourceRootDetectionUtil.java#L44

On the other hand it should not be much heavier than the indexing task that is going to be done right after attachment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw issues in "Find Usages" with sources detection as well. I do think that proper and complete IJ project model is required since we are attaching sources there and they are incorrect. As a result it can cause some other source navigation/usage issues.

I do agree that IO cost might be too high and open to any discussions here.

This is one of the reasons to introduce custom registry key to enable this only if this is the only way to have proper sources.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but the sources are attached on-demand, so the whole change does not affect find usages unless you try to jump to sources for all the libraries. So please let's do it this way. The behavior will be exactly the same, but we will guarantee that the heavy detection won't be called accidentally.

Apart from this, if you change the code in BlazeAttachSourceProvider.attachSources and put the new code in java module, you will fix the clion compatiblity issue for free.

@sgowroji sgowroji added the product: IntelliJ IntelliJ plugin label Jul 20, 2023
Copy link
Collaborator

@tpasternak tpasternak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So let's merge it (with the feature flag turned off by default), but apart from in-line comments, please adjust the examples/java/greeting_project in the way it can be used to show the issue.

base/src/META-INF/blaze-base.xml Outdated Show resolved Hide resolved
VirtualFile jarFile = VirtualFileManager.getInstance().findFileByUrl(pathToUrl(file));
List<VirtualFile> candidates = Collections.emptyList();
if (jarFile != null) {
candidates = JavaVfsSourceRootDetectionUtil.suggestRoots(jarFile, new EmptyProgressIndicator());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use ProgressManager instead of EmptyProgressIndicator (ideally with cancellation handled correctly in case this was really slow)

1. Moved some jar class/source related logic to BazelJarLibrary class from `base` module LibraryModifier.
2. Added proper progress indicator.
3. Applied registry key description edits suggestions.
@dkashyn-sfdc
Copy link
Contributor Author

please adjust the examples/java/greeting_project in the way it can be used to show the issue.

Not sure what kind of changes I can make in those sample projects... should I create new package with glob and custom sources placement? How to make sure that registry key is used for that package?

@dkashyn-sfdc
Copy link
Contributor Author

@tpasternak could you please check again? Addressed all but 1 review comments.

Comment on lines 79 to 95
private String pathToUrl(File path) {
String name = path.getName();
boolean isJarFile =
FileUtilRt.extensionEquals(name, "jar")
|| FileUtilRt.extensionEquals(name, "srcjar")
|| FileUtilRt.extensionEquals(name, "zip");
// .jar files require an URL with "jar" protocol.
String protocol =
isJarFile
? StandardFileSystems.JAR_PROTOCOL
: VirtualFileSystemProvider.getInstance().getSystem().getProtocol();
String filePath = FileUtil.toSystemIndependentName(path.getPath());
String url = VirtualFileManager.constructUrl(protocol, filePath);
if (isJarFile) {
url += URLUtil.JAR_SEPARATOR;
}
return url;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please only move this code to the original place (and change access modifier to static). We regularly cherry pick cahnges from the google branch, so we want to keep the changes as small as possible

@dkashyn-sfdc
Copy link
Contributor Author

For some reason, dkashyn-sfdc@f7d0e7c is not reflected in the PR.

@tpasternak tpasternak merged commit 53cf068 into bazelbuild:master Aug 2, 2023
1 check passed
@github-actions github-actions bot removed the awaiting-review Awaiting review from Bazel team on PRs label Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
product: IntelliJ IntelliJ plugin
Projects
Development

Successfully merging this pull request may close these issues.

4 participants