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

Add -no-relative-path: flag to control indexing of generated files #611

Merged
merged 1 commit into from
Jul 12, 2023

Conversation

olafurpg
Copy link
Member

Previously, the SemanticDB compiler plugin errored when indexing auto-generated files outside of the configured -sourceroot directory (which is automatically inferred for Bazel builds). This behavior was undesirable because:

  • There's no good workaround for the issue
  • The error message was cryptic making it difficult to understand what went wrong

For some cases, we were able to detect this situation for Bazel and ignore the indexed file while printing an informative message, but this behavior was also undesirable because we skipping these files means that we can't render hover messages for symbols in those generated files.

This PR fixes the issue by adding a configurable -no-relative-path: flag with the following valid options:

  • index_anyways (default): indexes the file but with no guarantee that it's possible to recover the location of the original generated file. This allows us to display accurate hover tooltips for symbols in these files even if "Go to definition" won't work.
  • skip: silently ignored these files.
  • warning: ignore these files and print a message explaining it was skipped.
  • error: fail the compilation process (old default).

Test plan

Manually tested this in the example Bazel workspace with the following commands:

❯ cd examples/bazel-example
❯ bazel build //... --@scip_java//semanticdb-javac:enabled=true
INFO: Analyzed 4 targets (0 packages loaded, 0 targets configured).
INFO: Found 4 targets...
INFO: Elapsed time: 0.102s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
❯ find bazel-bin/ -type f -name '*.semanticdb'
bazel-bin//src/main/java/example/example.semanticdb/META-INF/semanticdb/src/main/java/example/Example.java.semanticdb
bazel-bin//src/main/java/example/_javac/example/libexample_classes/META-INF/semanticdb/src/main/java/example/Example.java.semanticdb
bazel-bin//src/main/java/source-generator-example/animal.semanticdb/META-INF/semanticdb/src/main/java/source-generator-example/Animal.java.semanticdb
bazel-bin//src/main/java/source-generator-example/_javac/animal/libanimal_classes/META-INF/semanticdb/bazel-out/darwin_arm64-fastbuild/bin/src/main/java/source-generator-example/_javac/animal/libanimal_sources/AutoValue_Animal.java.semanticdb
bazel-bin//src/main/java/source-generator-example/_javac/animal/libanimal_classes/META-INF/semanticdb/src/main/java/source-generator-example/Animal.java.semanticdb

Observe that the generated file does not use the no-relative-path/NUMBER.FILENAME.semanticdb logic in this PR. To be sure, I manually tested that code path by changing the implementation a bit and confirmed that it generates valid relative paths under META-INF/semanticdb/no-relative-path/....

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Previously, the SemanticDB compiler plugin errored when indexing
auto-generated files outside of the configured `-sourceroot` directory
(which is automatically inferred for Bazel builds). This behavior was
undesirable because:

- There's no good workaround for the issue
- The error message was cryptic making it difficult to understand what
  went wrong

For some cases, we were able to detect this situation for Bazel and
ignore the indexed file while printing an informative message, but this
behavior was also undesirable because we skipping these files means that
we can't render hover messages for symbols in those generated files.

This PR fixes the issue by adding a configurable `-no-relative-path:`
flag with the following valid options:

- `index_anyways` (default): indexes the file but with no guarantee that
  it's possible to recover the location of the original generated file.
  This allows us to display accurate hover tooltips for symbols in these
  files even if "Go to definition" won't work.
- `skip`: silently ignored these files.
- `warning`: ignore these files and print a message explaining it was
  skipped.
- `error`: fail the compilation process (old default).
@olafurpg olafurpg requested a review from keynmol July 12, 2023 09:41
@@ -1,18 +1,20 @@
"""Java rules that automatically register the SemanticDB compiler plugin based on the presence of a string flag."""
load("@rules_java//java:defs.bzl", native_java_library="java_library", native_java_binary="java_binary")
Copy link
Member Author

Choose a reason for hiding this comment

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

Unrelated formatting changes because format-on-save 🤦🏻


if (options.uriScheme == UriScheme.BAZEL && options.generatedTargetRoot != null) {
try {
if (absolutePath.toRealPath().startsWith(options.generatedTargetRoot)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

@keynmol FYI I kept options.generatedTargetRoot even if it's no longer used.

// In the future, we may want to additionally embed the full text contents of these files
// so that it's possible to browse generated files with precise code navigation.
String uniqueFilename =
String.format("%d.%s.semanticdb", ++noRelativePathCounter, absolutePath.getFileName());
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have any guarantees about javac being invoked only once per Bazel target?

Otherwise the noRelativePathCounter in second invocation will be reset and files can start overwriting each other

Copy link
Member Author

Choose a reason for hiding this comment

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

The output of rebuilding the same Bazel target is guaranteed to produce identical results, unless the build is buggy. You have to use different targets if you're cross-building the same set of sources.

return Result.error(
String.format(
"Unable to detect the relative path of '%s'. A common reason for this error is that the file is that this file is auto-generated. "
+ "To fix this problem, either configure the -sourceroot:PATH flag to be the parent directory of all indexed files, or "
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think we can change the error message for Bazel specifically to remove the -sourceroot part, which we know is not sufficient?

String.format(
"Unable to detect the relative path of '%s'. A common reason for this error is that the file is that this file is auto-generated. "
+ "To fix this problem, either configure the -sourceroot:PATH flag to be the parent directory of all indexed files, or "
+ "configure -no-relative-path:VALUE flag to have one of the following values: index_anyway, skip, warning.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use NoRelativePathMode.values() again to avoid things drifting if you were to change values/add new ones

@olafurpg
Copy link
Member Author

I will address the unresolved comments separately

@olafurpg olafurpg merged commit 00c8ed5 into main Jul 12, 2023
@olafurpg olafurpg deleted the olafurpg/no-relative-path branch July 12, 2023 14:25
olafurpg added a commit that referenced this pull request Jul 13, 2023
This commit addresses unresolved comments from the PR #611
olafurpg added a commit that referenced this pull request Jul 13, 2023
This commit addresses unresolved comments from the PR #611
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants