-
Notifications
You must be signed in to change notification settings - Fork 69
[WIP] Add buildTarget/wrappedSources to protocol
#673
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
base: master
Are you sure you want to change the base?
Conversation
"buildTarget/wrappedSources" is a way for build tools to report wrapped Scala sources, which are sources that are wrapped with some text to make them valid Scala code. This was introduced by scala-cli and metals as a bespoke extension to the build-server-protocol. This adds it to the official protocol.
| * supported or not. | ||
| */ | ||
| @JsonRequest("buildTarget/wrappedSources") | ||
| CompletableFuture<WrappedSourcesResult> buildTargetWrappedSources(WrappedSourcesParams params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we actually have a ScriptBuildServer as a separate thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should we?
It's a capability that can be declared as supported via normal capabilities. Also, nothing stops someone to write a script wrapper for java which does a similar thing to what scala-cli does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, I was just being cautious since we don't have too many server implementing this, but I guess it's totally fine if we add a capability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is probably no clear line to cut between an capability and an extension. They mostly differ in how they get enabled. And this story isn't completely written for modularity.
@lolgab What stops us to use the wrapperSources to use for Java files right away. Is there anything Scala specific?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lolgab What stops us to use the wrapperSources to use for Java files right away. Is there anything Scala specific?
I don't think anything stops us, but other than the javadoc maybe, there is nothing Scala specific in this PR, unless I'm wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great.
| def buildTargetCompile(params: CompileParams): CompletableFuture[CompileResult] = ??? | ||
| def buildTargetDependencySources(params: DependencySourcesParams): CompletableFuture[DependencySourcesResult] = ??? | ||
| def buildTargetDependencyModules(params: DependencyModulesParams): CompletableFuture[DependencyModulesResult] = ??? | ||
| def buildTargetInverseSources(params: InverseSourcesParams): CompletableFuture[InverseSourcesResult] = ??? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happened to buildTargetInverseSources here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ops, reverting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added it back
|
|
||
| /// The wrapped sources request is sent from the client to the server to query for | ||
| /// the list of build targets containing wrapped sources. Wrapped sources are script | ||
| /// sources that are wrapped by the build tool with some top and bottom wrappers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me as uninvolved person the use case is not really clear. Can you explain a bit more what this means and why it warrants a separate request?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically scala scripts are not "real" scala code, they are text files that can become Scala code only after wrapping them with some code to make them real.
For example:
println("Hello world!")doesn't compile in Scala.
But if you wrap the code with:
val top = s"""object main {
def main(args: Array[String]): Unit = {
"""and
val bottom = """ }
}
"""it becomes valid Scala code.
Since it's not valid Scala code, IDEs can't parse them correctly, unless you tell them about this processing. scala-cli created this extension to have IDE supports on ammonite and scala-cli scripts.
Of course what I said should be better summarized and added to the documentation as javadcod and smithy comment.
why it warrants a separate request?
This I don't know. I'm just following what's there since this is already used by scala-cli as a bespoke extension. If this can be achieved in a better way, let me know, I'm happy to update the PR.
I'm not very familiar with the BSP protocol other than some bugfixes I did in the Mill's implementation.
| public Boolean getWrappedSourcesProvider() { | ||
| return this.wrappedSourcesProvider; | ||
| } | ||
|
|
||
| public void setWrappedSourcesProvider(final Boolean wrappedSourcesProvider) { | ||
| this.wrappedSourcesProvider = wrappedSourcesProvider; | ||
| } | ||
|
|
||
| public Boolean getWrappedSourcesProvider() { | ||
| return this.wrappedSourcesProvider; | ||
| } | ||
|
|
||
| public void setWrappedSourcesProvider(final Boolean wrappedSourcesProvider) { | ||
| this.wrappedSourcesProvider = wrappedSourcesProvider; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These duplicate entries don't look right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, boolean would be the better type here, since it can't be null.
|
|
||
| private Boolean inverseSourcesProvider; | ||
|
|
||
| private Boolean wrappedSourcesProvider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value is uninitialized, like all the others. Better use boolean for such simple on/off settings.
| structure WrappedSourceItem { | ||
| @required | ||
| uri: String | ||
| @required | ||
| generatedUri: String | ||
| @required | ||
| topWrapper: String | ||
| @required | ||
| bottomWrapper: String | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to add a new request for this? Or should we consider "wrapped sources" as part of buildTarget/sources ?
I would rather go with the second option, and add the optional topWrapper, bottomWrapper to the SourceItem:
structure SourceItem {
@required
uri: URI;
@required
kind: SourceItemKind;
@required
generated: boolean;
// optional
topWrapper: String;
// optional
bottomWrapper: String
}Or even better:
structure SourceItem {
@required
uri: URI;
@required
kind: SourceItemKind;
@required
generated: boolean;
// optional
wrapper: SourceWrapper;
}
structure SourceWrapper {
@required
prefix: String;
@required
suffix: String;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need to add generatedUri to have the link, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes I missed that part.
So it seems a "wrapped source" is the source of a generated source file. And we want to have the support of our IDE in it because it looks a lot like a Scala file.
But this seems to be a special case of something more general which are the source files of source generation. In this case it is an sc file that generates a Scala file, but it could also be a proto, json, smithy or twirl file that generates Scala code.
So can we generalize that request? Something like this maybe:
@jsonRequest("buildTarget/sourceGenerationSources")
operation BuildTargetSourceGenerationSources {
input: SourceGenerationSourcesParams
output: SourceGenerationSourcesResult
}
structure SourceGenerationSourcesItem {
@required
uri: String
@required
generatedUri: String
// optional
data: SourceGenerationSourcesItemData
}
// in the scala extension
@dataKind(kind: "wrapped-scala-source", extends: [SourceGenerationSourcesItemData])
structure WrappedScalaSource {
@required
prefix: String
@required
suffix: String
}|
So, what's the status of this PR? There are some unaddressed comments, but besides that, it would be nice to get some general feedback (of someone with merge rights, which I don't have) regarding the direction. Will it get merged eventually? It's an obviously needed feature for tools like Mill or Scala-CLI. It doesn't break compatibility. So it shouldn't really stay for so long in the review queue. |
|
Sorry for the dragging, it dropped off my radar. |
👍 This looks like a compromise. |
|
For the Mill use-case I managed to workaround the missing protocol message by parsing the generated sources and get the necessary data from them. Still, Metals doesn't work as expected. |
"buildTarget/wrappedSources" is a way for build tools to report wrapped Scala sources, which are sources that are wrapped with some text to make them valid Scala code.
This was introduced by scala-cli and metals as a bespoke extension to the build-server-protocol.
This adds it to the official protocol.