From b914d1cbc21db65dae3ad36b1f345438ae756df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Tue, 6 May 2025 03:46:59 +0200 Subject: [PATCH 1/4] Replace bsp codegen with smithy4s-bsp --- bspJsonRpc/smithy/bsp.smithy | 1412 ----------------- bspJsonRpc/smithy/jvm.smithy | 170 -- bspJsonRpc/smithy/scala.smithy | 337 ---- build.sc | 12 +- sls/src/org/scala/abusers/sls/BspClient.scala | 12 +- .../org/scala/abusers/sls/DocumentSync.scala | 2 - .../abusers/sls/SimpleLanguageServer.scala | 5 +- .../scala/abusers/sls/DocumentSyncTests.scala | 8 +- 8 files changed, 19 insertions(+), 1939 deletions(-) delete mode 100644 bspJsonRpc/smithy/bsp.smithy delete mode 100644 bspJsonRpc/smithy/jvm.smithy delete mode 100644 bspJsonRpc/smithy/scala.smithy diff --git a/bspJsonRpc/smithy/bsp.smithy b/bspJsonRpc/smithy/bsp.smithy deleted file mode 100644 index c78d0ec..0000000 --- a/bspJsonRpc/smithy/bsp.smithy +++ /dev/null @@ -1,1412 +0,0 @@ -$version: "2" - -namespace bsp - -use alloy#untagged -use jsonrpclib#jsonNotification -use jsonrpclib#jsonRPC -use jsonrpclib#jsonRequest - -integer Integer - -/// A long is a 64-bit signed integer ranging from -2^63 to (2^63)-1 (inclusive). -long Long - -@jsonRPC -service BuildClient { - operations: [ - OnBuildShowMessage - OnBuildLogMessage - OnBuildPublishDiagnostics - OnBuildTargetDidChange - OnBuildTaskStart - OnBuildTaskProgress - OnBuildTaskFinish - OnRunPrintStdout - OnRunPrintStderr - ] -} - -@jsonRPC -service BuildServer { - operations: [ - BuildInitialize - OnBuildInitialized - BuildShutdown - OnBuildExit - WorkspaceBuildTargets - WorkspaceReload - BuildTargetSources - BuildTargetInverseSources - BuildTargetDependencySources - BuildTargetDependencyModules - BuildTargetResources - BuildTargetOutputPaths - BuildTargetCompile - BuildTargetRun - BuildTargetTest - DebugSessionStart - BuildTargetCleanCache - OnRunReadStdin - ] -} - -/// Build target contains metadata about an artifact (for example library, test, or binary artifact). Using vocabulary of other build tools: -/// -/// * sbt: a build target is a combined project + config. Example: -/// * a regular JVM project with main and test configurations will have 2 build targets, one for main and one for test. -/// * a single configuration in a single project that contains both Java and Scala sources maps to one BuildTarget. -/// * a project with crossScalaVersions 2.11 and 2.12 containing main and test configuration in each will have 4 build targets. -/// * a Scala 2.11 and 2.12 cross-built project for Scala.js and the JVM with main and test configurations will have 8 build targets. -/// * Pants: a pants target corresponds one-to-one with a BuildTarget -/// * Bazel: a bazel target corresponds one-to-one with a BuildTarget -/// -/// The general idea is that the BuildTarget data structure should contain only information that is fast or cheap to compute. -structure BuildTarget { - /// The target's unique identifier - @required - id: BuildTargetIdentifier - /// A human readable name for this target. - /// May be presented in the user interface. - /// Should be unique if possible. - /// The id.uri is used if None. - displayName: String - /// The directory where this target belongs to. Multiple build targets are allowed to map - /// to the same base directory, and a build target is not required to have a base directory. - /// A base directory does not determine the sources of a target, see buildTarget/sources. - baseDirectory: URI - /// Free-form string tags to categorize or label this build target. - /// For example, can be used by the client to: - /// - customize how the target should be translated into the client's project model. - /// - group together different but related targets in the user interface. - /// - display icons or colors in the user interface. - /// Pre-defined tags are listed in `BuildTargetTag` but clients and servers - /// are free to define new tags for custom purposes. - @required - tags: BuildTargetTags - /// The set of languages that this target contains. - /// The ID string for each language is defined in the LSP. - @required - languageIds: LanguageIds - /// The direct upstream build target dependencies of this build target - @required - dependencies: BuildTargetIdentifiers - /// The capabilities of this build target. - @required - capabilities: BuildTargetCapabilities - /// Language-specific metadata about this target. - /// See ScalaBuildTarget as an example. - data: BuildTargetData -} - -/// A list of predefined tags that can be used to categorize build targets. -enum BuildTargetTag { - /// Target contains re-usable functionality for downstream targets. May have any - /// combination of capabilities. - LIBRARY = "library" - /// Target contains source code for producing any kind of application, may have - /// but does not require the `canRun` capability. - APPLICATION = "application" - /// Target contains source code for testing purposes, may have but does not - /// require the `canTest` capability. - TEST = "test" - /// Target contains source code for integration testing purposes, may have - /// but does not require the `canTest` capability. - /// The difference between "test" and "integration-test" is that - /// integration tests traditionally run slower compared to normal tests - /// and require more computing resources to execute. - INTEGRATION_TEST = "integration-test" - /// Target contains source code to measure performance of a program, may have - /// but does not require the `canRun` build target capability. - BENCHMARK = "benchmark" - /// Target should be ignored by IDEs. - NO_IDE = "no-ide" - /// Actions on the target such as build and test should only be invoked manually - /// and explicitly. For example, triggering a build on all targets in the workspace - /// should by default not include this target. - /// The original motivation to add the "manual" tag comes from a similar functionality - /// that exists in Bazel, where targets with this tag have to be specified explicitly - /// on the command line. - MANUAL = "manual" -} - -list BuildTargetTags { - member: BuildTargetTag -} - -/// Clients can use these capabilities to notify users what BSP endpoints can and -/// cannot be used and why. -structure BuildTargetCapabilities { - /// This target can be compiled by the BSP server. - canCompile: Boolean - /// This target can be tested by the BSP server. - canTest: Boolean - /// This target can be run by the BSP server. - canRun: Boolean - /// This target can be debugged by the BSP server. - canDebug: Boolean -} - -/// A unique identifier for a target, can use any URI-compatible encoding as long as it is unique within the workspace. -/// Clients should not infer metadata out of the URI structure such as the path or query parameters, use `BuildTarget` instead. -structure BuildTargetIdentifier { - /// The target's Uri - @required - uri: URI -} - -/// The Task Id allows clients to _uniquely_ identify a BSP task and establish a client-parent relationship with another task id. -structure TaskId { - /// A unique identifier - @required - id: Identifier - /// The parent task ids, if any. A non-empty parents field means - /// this task is a sub-task of every parent task id. The child-parent - /// relationship of tasks makes it possible to render tasks in - /// a tree-like user interface or inspect what caused a certain task - /// execution. - /// OriginId should not be included in the parents field, there is a separate - /// field for that. - parents: Identifiers -} - -string Identifier - -list Identifiers { - member: Identifier -} - -/// Included in notifications of tasks or requests to signal the completion state. -intEnum StatusCode { - /// Execution was successful. - OK = 1 - /// Execution failed. - ERROR = 2 - /// Execution was cancelled. - CANCELLED = 3 -} - -/// A resource identifier that is a valid URI according to rfc3986: -/// https://tools.ietf.org/html/rfc3986 -string URI - -list URIs { - member: URI -} - -list Languages { - member: String -} - -/// Structure describing how to start a BSP server and the capabilities it supports. -structure BspConnectionDetails { - /// The name of the BSP server. - @required - name: String - /// Arguments to pass to the BSP server. - @required - argv: Arguments - /// The version of the BSP server. - @required - version: String - /// Supported BSP version. - @required - bspVersion: String - /// The languages supported by the BSP server. - @required - languages: Languages -} - -/// Like the language server protocol, the initialize request is sent as the first request from the client to the server. -/// If the server receives a request or notification before the initialize request it should act as follows: -/// -/// * For a request the response should be an error with code: -32002. The message can be picked by the server. -/// * Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request. -/// -/// Until the server has responded to the initialize request with an InitializeBuildResult, the client must not send any additional -/// requests or notifications to the server. -@jsonRequest("build/initialize") -operation BuildInitialize { - input: InitializeBuildParams - output: InitializeBuildResult -} - -/// Like the language server protocol, the initialized notification is sent from the -/// client to the server after the client received the result of the initialize -/// request but before the client is sending any other request or notification to -/// the server. The server can use the initialized notification for example to -/// initialize intensive computation such as dependency resolution or compilation. -/// The initialized notification may only be sent once. -@jsonNotification("build/initialized") -operation OnBuildInitialized { - -} - -/// Like the language server protocol, the shutdown build request is sent from the -/// client to the server. It asks the server to shut down, but to not exit -/// (otherwise the response might not be delivered correctly to the client). There -/// is a separate exit notification that asks the server to exit. -@jsonRequest("build/shutdown") -operation BuildShutdown { - -} - -/// Like the language server protocol, a notification to ask the server to exit its process. The server should exit with success code 0 -/// if the shutdown request has been received before; otherwise with error code 1. -@jsonNotification("build/exit") -operation OnBuildExit { - -} - -/// The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface. -/// -/// A build/showMessage notification is similar to LSP's window/showMessage, except for a few additions like id and originId. -@jsonNotification("build/showMessage") -operation OnBuildShowMessage { - input: ShowMessageParams -} - -/// The log message notification is sent from a server to a client to ask the client to log a particular message in its console. -/// -/// A build/logMessage notification is similar to LSP's window/logMessage, except for a few additions like id and originId. -@jsonNotification("build/logMessage") -operation OnBuildLogMessage { - input: LogMessageParams -} - -/// The Diagnostics notification are sent from the server to the client to signal results of validation runs. -/// -/// When reset is true, the client must clean all previous diagnostics associated with the same textDocument and -/// buildTarget and set instead the diagnostics in the request. This is the same behaviour as PublishDiagnosticsParams -/// in the LSP. When reset is false, the diagnostics are added to the last active diagnostics, allowing build tools to -/// stream diagnostics to the client. -/// -/// It is the server's responsibility to manage the lifetime of the diagnostics by using the appropriate value in the reset field. -/// Clients generate new diagnostics by calling any BSP endpoint that triggers a buildTarget/compile, such as buildTarget/compile, buildTarget/test and buildTarget/run. -/// -/// If the computed set of diagnostic is empty, the server must push an empty array with reset set to true, in order to clear previous diagnostics. -/// -/// The optional originId field in the definition of PublishDiagnosticsParams can be used by clients to know which request originated the notification. -/// This field will be defined if the client defined it in the original request that triggered this notification. -@jsonNotification("build/publishDiagnostics") -operation OnBuildPublishDiagnostics { - input: PublishDiagnosticsParams -} - -/// The workspace build targets request is sent from the client to the server to ask -/// for the list of all available build targets in the workspace. -@jsonRequest("workspace/buildTargets") -operation WorkspaceBuildTargets { - output: WorkspaceBuildTargetsResult -} - -/// The `reload` request is sent from the client to instruct the build server to reload -/// the build configuration. This request should be supported by build tools that keep -/// their state in memory. If the `reload` request returns with an error, it's expected -/// that other requests respond with the previously known "good" state. -@jsonRequest("workspace/reload") -operation WorkspaceReload { - -} - -/// The build target changed notification is sent from the server to the client to -/// signal a change in a build target. The server communicates during the initialize -/// handshake whether this method is supported or not. -@jsonNotification("buildTarget/didChange") -operation OnBuildTargetDidChange { - input: DidChangeBuildTarget -} - -/// The build target sources request is sent from the client to the server to query -/// for the list of text documents and directories that are belong to a build -/// target. The sources response must not include sources that are external to the -/// workspace, see `buildTarget/dependencySources`. -@jsonRequest("buildTarget/sources") -operation BuildTargetSources { - input: SourcesParams - output: SourcesResult -} - -/// The inverse sources request is sent from the client to the server to query for -/// the list of build targets containing a text document. The server communicates -/// during the initialize handshake whether this method is supported or not. This -/// request can be viewed as the inverse of `buildTarget/sources`, except it only -/// works for text documents and not directories. -@jsonRequest("buildTarget/inverseSources") -operation BuildTargetInverseSources { - input: InverseSourcesParams - output: InverseSourcesResult -} - -/// The build target dependency sources request is sent from the client to the -/// server to query for the sources of build target dependencies that are external -/// to the workspace. The dependency sources response must not include source files -/// that belong to a build target within the workspace, see `buildTarget/sources`. -/// -/// The server communicates during the initialize handshake whether this method is -/// supported or not. This method can for example be used by a language server on -/// `textDocument/definition` to "Go to definition" from project sources to -/// dependency sources. -@jsonRequest("buildTarget/dependencySources") -operation BuildTargetDependencySources { - input: DependencySourcesParams - output: DependencySourcesResult -} - -/// The build target dependency modules request is sent from the client to the -/// server to query for the libraries of build target dependencies that are external -/// to the workspace including meta information about library and their sources. -/// It's an extended version of `buildTarget/sources`. -@jsonRequest("buildTarget/dependencyModules") -operation BuildTargetDependencyModules { - input: DependencyModulesParams - output: DependencyModulesResult -} - -/// The build target resources request is sent from the client to the server to -/// query for the list of resources of a given list of build targets. -/// -/// A resource is a data dependency required to be present in the runtime classpath -/// when a build target is run or executed. The server communicates during the -/// initialize handshake whether this method is supported or not. -/// -/// This request can be used by a client to highlight the resources in a project -/// view, for example. -@jsonRequest("buildTarget/resources") -operation BuildTargetResources { - input: ResourcesParams - output: ResourcesResult -} - -/// The build target output paths request is sent from the client to the server to -/// query for the list of output paths of a given list of build targets. -/// -/// An output path is a file or directory that contains output files such as build -/// artifacts which IDEs may decide to exclude from indexing. The server communicates -/// during the initialize handshake whether this method is supported or not. -@jsonRequest("buildTarget/outputPaths") -operation BuildTargetOutputPaths { - input: OutputPathsParams - output: OutputPathsResult -} - -/// The BSP server can inform the client on the execution state of any task in the -/// build tool. The execution of some tasks, such as compilation or tests, must -/// always be reported by the server. -/// -/// The server may also send additional task notifications for actions not covered -/// by the protocol, such as resolution or packaging. BSP clients can then display -/// this information to their users at their discretion. -/// -/// When beginning a task, the server may send `build/taskStart`, intermediate -/// updates may be sent in `build/taskProgress`. -/// -/// If a `build/taskStart` notification has been sent, the server must send -/// `build/taskFinish` on completion of the same task. -/// -/// `build/taskStart`, `build/taskProgress` and `build/taskFinish` notifications for -/// the same task must use the same `taskId`. -/// -/// Tasks that are spawned by another task should reference the originating task's -/// `taskId` in their own `taskId`'s `parent` field. Tasks spawned directly by a -/// request should reference the request's `originId` parent. -@jsonNotification("build/taskStart") -operation OnBuildTaskStart { - input: TaskStartParams -} - -/// After a `taskStart` and before `taskFinish` for a `taskId`, the server may send -/// any number of progress notifications. -@jsonNotification("build/taskProgress") -operation OnBuildTaskProgress { - input: TaskProgressParams -} - -/// A `build/taskFinish` notification must always be sent after a `build/taskStart` -/// with the same `taskId` was sent. -@jsonNotification("build/taskFinish") -operation OnBuildTaskFinish { - input: TaskFinishParams -} - -/// The compile build target request is sent from the client to the server to -/// compile the given list of build targets. The server communicates during the -/// initialize handshake whether this method is supported or not. This method can -/// for example be used by a language server before `textDocument/rename` to ensure -/// that all workspace sources typecheck correctly and are up-to-date. -@jsonRequest("buildTarget/compile") -operation BuildTargetCompile { - input: CompileParams - output: CompileResult -} - -/// The test build target request is sent from the client to the server to test the -/// given list of build targets. The server communicates during the initialize -/// handshake whether this method is supported or not. -/// -/// The "Implementation notes" section of the `buildTarget/run` request applies to -/// this request as well. -@jsonRequest("buildTarget/test") -operation BuildTargetTest { - input: TestParams - output: TestResult -} - -/// The run request is sent from the client to the server to run a build target. The -/// server communicates during the initialize handshake whether this method is -/// supported or not. -/// -/// Note that a run request containing only the target id is valid. -/// If no further parameters are provided, the server should use the default ones. -/// -/// Implementation notes: -/// -/// This request may trigger a compilation on the selected build targets. The server -/// is free to send any number of `build/task*`, `build/publishDiagnostics` and -/// `build/logMessage` notifications during compilation before completing the -/// response. -/// -/// The client will get a `originId` field in `RunResult` if and only if -/// the `originId` field in the `RunParams` is defined. -/// -/// Cancelling this request must kill the running process. -/// -/// If the BSP server wishes to forward the stdout and stderr streams of the running process -/// to the client, it can do so by sending `run/printStdout` and `run/printStderr` notifications. -/// -/// If the client wishes to send input to the running process, it can do so by sending -/// `run/readStdin` notifications to the server. -@jsonRequest("buildTarget/run") -operation BuildTargetRun { - input: RunParams - output: RunResult -} - -/// The debug request is sent from the client to the server to debug build target(s). The -/// server launches a [Microsoft DAP](https://microsoft.github.io/debug-adapter-protocol/) server -/// and returns a connection URI for the client to interact with. -@jsonRequest("debugSession/start") -operation DebugSessionStart { - input: DebugSessionParams - output: DebugSessionAddress -} - -/// The clean cache request is sent from the client to the server to reset any state -/// associated with a given build target. The state can live either in the build -/// tool or in the file system. -/// -/// The build tool defines the exact semantics of the clean cache request: -/// -/// 1. Stateless build tools are free to ignore the request and respond with a -/// successful response. -/// 2. Stateful build tools must ensure that invoking compilation on a target that -/// has been cleaned results in a full compilation. -@jsonRequest("buildTarget/cleanCache") -operation BuildTargetCleanCache { - input: CleanCacheParams - output: CleanCacheResult -} - -/// Represents the identifier of a BSP request. -string OriginId - -list BuildTargetIdentifiers { - member: BuildTargetIdentifier -} - -document BuildTargetData - -document InitializeBuildParamsData - -structure InitializeBuildParams { - /// Name of the client - @required - displayName: String - /// The version of the client - @required - version: String - /// The BSP version that the client speaks - @required - bspVersion: String - /// The rootUri of the workspace - @required - rootUri: URI - /// The capabilities of the client - @required - capabilities: BuildClientCapabilities - /// Additional metadata about the client - data: InitializeBuildParamsData -} - -structure BuildClientCapabilities { - /// The languages that this client supports. - /// The ID strings for each language is defined in the LSP. - /// The server must never respond with build targets for other - /// languages than those that appear in this list. - @required - languageIds: LanguageIds - /// Mirror capability to BuildServerCapabilities.jvmCompileClasspathProvider - /// The client will request classpath via `buildTarget/jvmCompileClasspath` so - /// it's safe to return classpath in ScalacOptionsItem empty. - jvmCompileClasspathReceiver: Boolean = false -} - -/// Language IDs are defined here -/// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem -string LanguageId - -list LanguageIds { - member: LanguageId -} - -document InitializeBuildResultData - -structure InitializeBuildResult { - /// Name of the server - @required - displayName: String - /// The version of the server - @required - version: String - /// The BSP version that the server speaks - @required - bspVersion: String - /// The capabilities of the build server - @required - capabilities: BuildServerCapabilities - /// Additional metadata about the server - data: InitializeBuildResultData -} - -/// The capabilities of the build server. -/// Clients can use these capabilities to notify users what BSP endpoints can and -/// cannot be used and why. -structure BuildServerCapabilities { - /// The languages the server supports compilation via method buildTarget/compile. - compileProvider: CompileProvider - /// The languages the server supports test execution via method buildTarget/test. - testProvider: TestProvider - /// The languages the server supports run via method buildTarget/run. - runProvider: RunProvider - /// The languages the server supports debugging via method debugSession/start. - debugProvider: DebugProvider - /// The server can provide a list of targets that contain a - /// single text document via the method buildTarget/inverseSources - inverseSourcesProvider: Boolean = false - /// The server provides sources for library dependencies - /// via method buildTarget/dependencySources - dependencySourcesProvider: Boolean = false - /// The server can provide a list of dependency modules (libraries with meta information) - /// via method buildTarget/dependencyModules - dependencyModulesProvider: Boolean = false - /// The server provides all the resource dependencies - /// via method buildTarget/resources - resourcesProvider: Boolean = false - /// The server provides all output paths - /// via method buildTarget/outputPaths - outputPathsProvider: Boolean = false - /// The server sends notifications to the client on build - /// target change events via buildTarget/didChange - buildTargetChangedProvider: Boolean = false - /// The server can respond to `buildTarget/jvmRunEnvironment` requests with the - /// necessary information required to launch a Java process to run a main class. - jvmRunEnvironmentProvider: Boolean = false - /// The server can respond to `buildTarget/jvmTestEnvironment` requests with the - /// necessary information required to launch a Java process for testing or - /// debugging. - jvmTestEnvironmentProvider: Boolean = false - /// The server can respond to `workspace/cargoFeaturesState` and - /// `setCargoFeatures` requests. In other words, supports Cargo Features extension. - cargoFeaturesProvider: Boolean = false - /// Reloading the build state through workspace/reload is supported - canReload: Boolean = false - /// The server can respond to `buildTarget/jvmCompileClasspath` requests with the - /// necessary information about the target's classpath. - jvmCompileClasspathProvider: Boolean = false -} - -@mixin -structure LanguageProvider { - @required - languageIds: LanguageIds -} - -structure CompileProvider with [LanguageProvider] {} - -structure RunProvider with [LanguageProvider] {} - -structure DebugProvider with [LanguageProvider] {} - -structure TestProvider with [LanguageProvider] {} - -@mixin -structure MessageParams { - /// the message type. - @required - type: MessageType - /// The task id if any. - task: TaskId - /// The request id that originated this notification. - /// The originId field helps clients know which request originated a notification in case several requests are handled by the - /// client at the same time. It will only be populated if the client defined it in the request that triggered this notification. - originId: OriginId - /// The actual message. - @required - message: String -} - -structure ShowMessageParams with [MessageParams] {} - -structure LogMessageParams with [MessageParams] {} - -intEnum MessageType { - /// An error message. - ERROR = 1 - /// A warning message. - WARNING = 2 - /// An information message. - INFO = 3 - /// A log message. - LOG = 4 -} - -structure PublishDiagnosticsParams { - /// The document where the diagnostics are published. - @required - textDocument: TextDocumentIdentifier - /// The build target where the diagnostics origin. - /// It is valid for one text document to belong to multiple - /// build targets, for example sources that are compiled against multiple - /// platforms (JVM, JavaScript). - @required - buildTarget: BuildTargetIdentifier - /// The request id that originated this notification. - originId: OriginId - /// The diagnostics to be published by the client. - @required - diagnostics: Diagnostics - /// Whether the client should clear the previous diagnostics - /// mapped to the same `textDocument` and `buildTarget`. - @required - reset: Boolean -} - -document DiagnosticData - -/// Diagnostic is defined as it is in the LSP. -structure Diagnostic { - /// The range at which the message applies. - @required - range: Range - /// The diagnostic's severity. Can be omitted. If omitted it is up to the - /// client to interpret diagnostics as error, warning, info or hint. - severity: DiagnosticSeverity - /// The diagnostic's code, which might appear in the user interface. - code: DiagnosticCode - /// An optional property to describe the error code. - codeDescription: CodeDescription - /// A human-readable string describing the source of this - /// diagnostic, e.g. 'typescript' or 'super lint'. - source: String - /// The diagnostic's message. - @required - message: String - /// Additional metadata about the diagnostic. - tags: DiagnosticTags - /// An array of related diagnostic information, e.g. when symbol-names within - /// a scope collide all definitions can be marked via this property. - relatedInformation: DiagnosticRelatedInformations - /// A data entry field that is preserved between a - /// `textDocument/publishDiagnostics` notification and - /// `textDocument/codeAction` request. - data: DiagnosticData -} - -structure Position { - /// Line position in a document (zero-based). - @required - line: Integer - /// Character offset on a line in a document (zero-based) - /// - /// If the character value is greater than the line length it defaults back - /// to the line length. - @required - character: Integer -} - -structure Range { - /// The range's start position. - @required - start: Position - /// The range's end position. - @required - end: Position -} - -structure Location { - @required - uri: URI - @required - range: Range -} - -structure TextDocumentIdentifier { - /// The text document's URI. - @required - uri: URI -} - -list Diagnostics { - member: Diagnostic -} - -intEnum DiagnosticSeverity { - /// Reports an error. - ERROR = 1 - /// Reports a warning. - WARNING = 2 - /// Reports an information. - INFORMATION = 3 - /// Reports a hint. - HINT = 4 -} - -@untagged -union DiagnosticCode { - string: String - integer: Integer -} - -/// Structure to capture a description for an error code. -structure CodeDescription { - /// An URI to open with more information about the diagnostic error. - @required - href: URI -} - -intEnum DiagnosticTag { - /// Unused or unnecessary code. - /// - /// Clients are allowed to render diagnostics with this tag faded out - /// instead of having an error squiggle. - UNNECESSARY = 1 - /// Deprecated or obsolete code. - /// - /// Clients are allowed to rendered diagnostics with this tag strike through. - DEPRECATED = 2 -} - -list DiagnosticTags { - member: DiagnosticTag -} - -/// Represents a related message and source code location for a diagnostic. -/// This should be used to point to code locations that cause or are related to -/// a diagnostics, e.g when duplicating a symbol in a scope. -structure DiagnosticRelatedInformation { - /// The location of this related diagnostic information. - @required - location: Location - /// The message of this related diagnostic information. - @required - message: String -} - -list DiagnosticRelatedInformations { - member: DiagnosticRelatedInformation -} - -structure WorkspaceBuildTargetsResult { - /// The build targets in this workspace that - /// contain sources with the given language ids. - @required - targets: BuildTargets -} - -list BuildTargets { - member: BuildTarget -} - -structure DidChangeBuildTarget { - @required - changes: BuildTargetEvents -} - -document BuildTargetEventData - -structure BuildTargetEvent { - /// The identifier for the changed build target - @required - target: BuildTargetIdentifier - /// The kind of change for this build target - kind: BuildTargetEventKind - /// Any additional metadata about what information changed. - data: BuildTargetEventData -} - -list BuildTargetEvents { - member: BuildTargetEvent -} - -/// The `BuildTargetEventKind` information can be used by clients to trigger -/// reindexing or update the user interface with the new information. -intEnum BuildTargetEventKind { - /// The build target is new. - CREATED = 1 - /// The build target has changed. - CHANGED = 2 - /// The build target has been deleted. - DELETED = 3 -} - -structure SourcesParams { - @required - targets: BuildTargetIdentifiers -} - -structure SourcesResult { - @required - items: SourcesItems -} - -structure SourcesItem { - @required - target: BuildTargetIdentifier - /// The text documents or and directories that belong to this build target. - @required - sources: SourceItems - /// The root directories from where source files should be relativized. - /// Example: ["file://Users/name/dev/metals/src/main/scala"] - roots: URIs -} - -list SourcesItems { - member: SourcesItem -} - -document SourceItemData - -structure SourceItem { - /// Either a text document or a directory. A directory entry must end with a forward - /// slash "/" and a directory entry implies that every nested text document within the - /// directory belongs to this source item. - @required - uri: URI - /// Type of file of the source item, such as whether it is file or directory. - @required - kind: SourceItemKind - /// Indicates if this source is automatically generated by the build and is not - /// intended to be manually edited by the user. - @required - generated: Boolean - /// Language-specific metadata about this source item. - data: SourceItemData -} - -list SourceItems { - member: SourceItem -} - -intEnum SourceItemKind { - /// The source item references a normal file. - FILE = 1 - /// The source item references a directory. - DIRECTORY = 2 -} - -structure InverseSourcesParams { - @required - textDocument: TextDocumentIdentifier -} - -structure InverseSourcesResult { - @required - targets: BuildTargetIdentifiers -} - -structure DependencySourcesParams { - @required - targets: BuildTargetIdentifiers -} - -structure DependencySourcesResult { - @required - items: DependencySourcesItems -} - -structure DependencySourcesItem { - @required - target: BuildTargetIdentifier - /// List of resources containing source files of the - /// target's dependencies. - /// Can be source files, jar files, zip files, or directories. - @required - sources: URIs -} - -list DependencySourcesItems { - member: DependencySourcesItem -} - -structure DependencyModulesParams { - @required - targets: BuildTargetIdentifiers -} - -structure DependencyModulesResult { - @required - items: DependencyModulesItems -} - -list DependencyModules { - member: DependencyModule -} - -structure DependencyModulesItem { - @required - target: BuildTargetIdentifier - @required - modules: DependencyModules -} - -list DependencyModulesItems { - member: DependencyModulesItem -} - -document DependencyModuleData - -structure DependencyModule { - /// Module name - @required - name: String - /// Module version - @required - version: String - /// Language-specific metadata about this module. - /// See MavenDependencyModule as an example. - data: DependencyModuleData -} - -structure ResourcesParams { - @required - targets: BuildTargetIdentifiers -} - -structure ResourcesResult { - @required - items: ResourcesItems -} - -structure ResourcesItem { - @required - target: BuildTargetIdentifier - /// List of resource files. - @required - resources: URIs -} - -list ResourcesItems { - member: ResourcesItem -} - -structure OutputPathsParams { - @required - targets: BuildTargetIdentifiers -} - -structure OutputPathsResult { - @required - items: OutputPathsItems -} - -structure OutputPathsItem { - /// A build target to which output paths item belongs. - @required - target: BuildTargetIdentifier - /// Output paths. - @required - outputPaths: OutputPathItems -} - -list OutputPathsItems { - member: OutputPathsItem -} - -structure OutputPathItem { - /// Either a file or a directory. A directory entry must end with a forward - /// slash "/" and a directory entry implies that every nested path within the - /// directory belongs to this output item. - @required - uri: URI - /// Type of file of the output item, such as whether it is file or directory. - @required - kind: OutputPathItemKind -} - -list OutputPathItems { - member: OutputPathItem -} - -intEnum OutputPathItemKind { - /// The output path item references a normal file. - FILE = 1 - /// The output path item references a directory. - DIRECTORY = 2 -} - -/// Task start notifications may contain an arbitrary interface in their `data` -/// field. The kind of interface that is contained in a notification must be -/// specified in the `dataKind` field. -/// -/// There are predefined kinds of objects for compile and test tasks, as described -/// in [[bsp#BuildTargetCompile]] and [[bsp#BuildTargetTest]] -document TaskStartData - -/// Task progress notifications may contain an arbitrary interface in their `data` -/// field. The kind of interface that is contained in a notification must be -/// specified in the `dataKind` field. -document TaskProgressData - -/// Task finish notifications may contain an arbitrary interface in their `data` -/// field. The kind of interface that is contained in a notification must be -/// specified in the `dataKind` field. -/// -/// There are predefined kinds of objects for compile and test tasks, as described -/// in [[bsp#BuildTargetCompile]] and [[bsp#BuildTargetTest]] -document TaskFinishData - -structure TaskStartParams { - /// Unique id of the task with optional reference to parent task id - @required - taskId: TaskId - /// A unique identifier generated by the client to identify this request. - originId: Identifier - /// Timestamp of when the event started in milliseconds since Epoch. - eventTime: Long - /// Message describing the task. - message: String - /// Optional metadata about the task. - /// Objects for specific tasks like compile, test, etc are specified in the protocol. - data: TaskStartData -} - -structure TaskProgressParams { - /// Unique id of the task with optional reference to parent task id - @required - taskId: TaskId - /// A unique identifier generated by the client to identify this request. - originId: Identifier - /// Timestamp of when the event started in milliseconds since Epoch. - eventTime: Long - /// Message describing the task. - message: String - /// If known, total amount of work units in this task. - total: Long - /// If known, completed amount of work units in this task. - progress: Long - /// Name of a work unit. For example, "files" or "tests". May be empty. - unit: String - /// Optional metadata about the task. - /// Objects for specific tasks like compile, test, etc are specified in the protocol. - data: TaskProgressData -} - -structure TaskFinishParams { - /// Unique id of the task with optional reference to parent task id - @required - taskId: TaskId - /// A unique identifier generated by the client to identify this request. - originId: Identifier - /// Timestamp of when the event started in milliseconds since Epoch. - eventTime: Long - /// Message describing the task. - message: String - /// Task completion status. - @required - status: StatusCode - /// Optional metadata about the task. - /// Objects for specific tasks like compile, test, etc are specified in the protocol. - data: TaskFinishData -} - -structure CompileParams { - /// A sequence of build targets to compile. - @required - targets: BuildTargetIdentifiers - /// A unique identifier generated by the client to identify this request. - /// The server may include this id in triggered notifications or responses. - originId: Identifier - /// Optional arguments to the compilation process. - arguments: Arguments -} - -list Arguments { - member: String -} - -map EnvironmentVariables { - key: String - value: String -} - -document CompileResultData - -structure CompileResult { - /// An optional request id to know the origin of this report. - originId: Identifier - /// A status code for the execution. - @required - statusCode: StatusCode - /// A field containing language-specific information, like products - /// of compilation or compiler-specific metadata the client needs to know. - data: CompileResultData -} - -/// The beginning of a compilation unit may be signalled to the client with a -/// `build/taskStart` notification. When the compilation unit is a build target, the -/// notification's `dataKind` field must be "compile-task" and the `data` field must -/// include a `CompileTask` object: -structure CompileTask { - @required - target: BuildTargetIdentifier -} - -/// The completion of a compilation task should be signalled with a -/// `build/taskFinish` notification. When the compilation unit is a build target, -/// the notification's `dataKind` field must be `compile-report` and the `data` -/// field must include a `CompileReport` object: -structure CompileReport { - /// The build target that was compiled. - @required - target: BuildTargetIdentifier - /// An optional request id to know the origin of this report. - @deprecated(message: "Use the field in TaskFinishParams instead") - originId: Identifier - /// The total number of reported errors compiling this target. - @required - errors: Integer - /// The total number of reported warnings compiling the target. - @required - warnings: Integer - /// The total number of milliseconds it took to compile the target. - time: Long - /// The compilation was a noOp compilation. - noOp: Boolean -} - -document TestParamsData - -structure TestParams { - /// A sequence of build targets to test. - @required - targets: BuildTargetIdentifiers - /// A unique identifier generated by the client to identify this request. - /// The server may include this id in triggered notifications or responses. - originId: Identifier - /// Optional arguments to the test execution engine. - arguments: Arguments - /// Optional environment variables to set before running the tests. - environmentVariables: EnvironmentVariables - /// Optional working directory - workingDirectory: URI - /// Language-specific metadata about for this test execution. - /// See ScalaTestParams as an example. - data: TestParamsData -} - -document TestResultData - -structure TestResult { - /// An optional request id to know the origin of this report. - originId: Identifier - /// A status code for the execution. - @required - statusCode: StatusCode - /// Language-specific metadata about the test result. - /// See ScalaTestParams as an example. - data: TestResultData -} - -/// The beginning of a testing unit may be signalled to the client with a -/// `build/taskStart` notification. When the testing unit is a build target, the -/// notification's `dataKind` field must be `test-task` and the `data` field must -/// include a `TestTask` object. -structure TestTask { - @required - target: BuildTargetIdentifier -} - -structure TestReport { - @deprecated(message: "Use the field in TaskFinishParams instead") - originId: Identifier - /// The build target that was compiled. - @required - target: BuildTargetIdentifier - /// The total number of successful tests. - @required - passed: Integer - /// The total number of failed tests. - @required - failed: Integer - /// The total number of ignored tests. - @required - ignored: Integer - /// The total number of cancelled tests. - @required - cancelled: Integer - /// The total number of skipped tests. - @required - skipped: Integer - /// The total number of milliseconds tests take to run (e.g. doesn't include compile times). - time: Long -} - -structure TestStart { - /// Name or description of the test. - @required - displayName: String - /// Source location of the test, as LSP location. - location: Location -} - -document TestFinishData - -structure TestFinish { - /// Name or description of the test. - @required - displayName: String - /// Information about completion of the test, for example an error message. - message: String - /// Completion status of the test. - @required - status: TestStatus - /// Source location of the test, as LSP location. - location: Location - /// Optionally, structured metadata about the test completion. - /// For example: stack traces, expected/actual values. - data: TestFinishData -} - -intEnum TestStatus { - /// The test passed successfully. - PASSED = 1 - /// The test failed. - FAILED = 2 - /// The test was marked as ignored. - IGNORED = 3 - /// The test execution was cancelled. - CANCELLED = 4 - /// The was not included in execution. - SKIPPED = 5 -} - -document RunParamsData - -structure RunParams { - /// The build target to run. - @required - target: BuildTargetIdentifier - /// A unique identifier generated by the client to identify this request. - /// The server may include this id in triggered notifications or responses. - originId: Identifier - /// Optional arguments to the executed application. - arguments: Arguments - /// Optional environment variables to set before running the application. - environmentVariables: EnvironmentVariables - /// Optional working directory - workingDirectory: URI - /// Language-specific metadata for this execution. - /// See ScalaMainClass as an example. - data: RunParamsData -} - -structure RunResult { - /// An optional request id to know the origin of this report. - originId: Identifier - /// A status code for the execution. - @required - statusCode: StatusCode -} - -document DebugSessionParamsData - -structure DebugSessionParams { - /// A sequence of build targets affected by the debugging action. - @required - targets: BuildTargetIdentifiers - /// Language-specific metadata for this execution. - /// See ScalaMainClass as an example. - data: DebugSessionParamsData -} - -structure DebugSessionAddress { - /// The Debug Adapter Protocol server's connection uri - @required - uri: URI -} - -structure CleanCacheParams { - /// The build targets to clean. - @required - targets: BuildTargetIdentifiers -} - -structure CleanCacheResult { - /// Optional message to display to the user. - message: String - /// Indicates whether the clean cache request was performed or not. - @required - cleaned: Boolean -} - -@unstable -structure PrintParams { - /// The id of the request. - @required - originId: Identifier - /// Relevant only for test tasks. - /// Allows to tell the client from which task the output is coming from. - task: TaskId - /// Message content can contain arbitrary bytes. - /// They should be escaped as per [javascript encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings) - @required - message: String -} - -/// Notification sent from the server to the client when the target being run or tested -/// prints something to stdout. -@unstable -@jsonNotification("run/printStdout") -operation OnRunPrintStdout { - input: PrintParams -} - -/// Notification sent from the server to the client when the target being run or tested -/// prints something to stderr. -@unstable -@jsonNotification("run/printStderr") -operation OnRunPrintStderr { - input: PrintParams -} - -@unstable -structure ReadParams { - /// The id of the request. - @required - originId: Identifier - /// Relevant only for test tasks. - /// Allows to tell the client from which task the output is coming from. - task: TaskId - /// Message content can contain arbitrary bytes. - /// They should be escaped as per [javascript encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings) - @required - message: String -} - -/// Notification sent from the client to the server when the user wants to send -/// input to the stdin of the running target. -@unstable -@jsonNotification("run/readStdin") -operation OnRunReadStdin { - input: ReadParams -} diff --git a/bspJsonRpc/smithy/jvm.smithy b/bspJsonRpc/smithy/jvm.smithy deleted file mode 100644 index 719d4eb..0000000 --- a/bspJsonRpc/smithy/jvm.smithy +++ /dev/null @@ -1,170 +0,0 @@ -$version: "2" - -namespace bsp.jvmext - -use bsp#Arguments -use bsp#BuildTargetData -use bsp#BuildTargetIdentifier -use bsp#BuildTargetIdentifiers -use bsp#EnvironmentVariables -use bsp#Identifier -use bsp#SourceItemData -use bsp#URI -use jsonrpclib#jsonNotification -use jsonrpclib#jsonRPC -use jsonrpclib#jsonRequest - -@jsonRPC -service JvmBuildServer { - operations: [ - BuildTargetJvmTestEnvironment, - BuildTargetJvmRunEnvironment, - BuildTargetJvmCompileClasspath - ] -} - -/// `JvmBuildTarget` is a basic data structure that contains jvm-specific -/// metadata, specifically JDK reference. -structure JvmBuildTarget { - /// Uri representing absolute path to jdk - /// For example: file:///usr/lib/jvm/java-8-openjdk-amd64 - javaHome: URI - /// The java version this target is supposed to use (can be set using javac `-target` flag). - /// For example: 1.8 - javaVersion: String -} - -structure JvmEnvironmentItem { - @required - target: BuildTargetIdentifier - @required - classpath: Classpath - @required - jvmOptions: JvmOptions - @required - workingDirectory: String - @required - environmentVariables: EnvironmentVariables - mainClasses: JvmMainClasses -} - -/// The JVM test environment request is sent from the client to the server in order to -/// gather information required to launch a Java process. This is useful when the -/// client wants to control the Java process execution, for example to enable custom -/// Java agents or launch a custom main class during unit testing or debugging -/// -/// The data provided by this endpoint may change between compilations, so it should -/// not be cached in any form. The client should ask for it right before test execution, -/// after all the targets are compiled. -@jsonRequest("buildTarget/jvmTestEnvironment") -operation BuildTargetJvmTestEnvironment { - input: JvmTestEnvironmentParams - output: JvmTestEnvironmentResult -} - -structure JvmTestEnvironmentParams { - @required - targets: BuildTargetIdentifiers - originId: Identifier -} - -structure JvmTestEnvironmentResult { - @required - items: JvmEnvironmentItems -} - -list JvmEnvironmentItems { - member: JvmEnvironmentItem -} - -/// Similar to `buildTarget/jvmTestEnvironment`, but returns environment -/// that should be used for regular exection of main classes, not for testing -@jsonRequest("buildTarget/jvmRunEnvironment") -operation BuildTargetJvmRunEnvironment { - input: JvmRunEnvironmentParams - output: JvmRunEnvironmentResult -} - -structure JvmRunEnvironmentParams { - @required - targets: BuildTargetIdentifiers - originId: Identifier -} - -structure JvmMainClass { - @required - className: String - @required - arguments: Arguments -} - -structure JvmRunEnvironmentResult { - @required - items: JvmEnvironmentItems -} - -list JvmMainClasses { - member: JvmMainClass -} - -list Classpath { - member: String -} - -list JvmOptions { - member: String -} - - -/// The build target classpath request is sent from the client to the server to -/// query the target for its compile classpath. -@jsonRequest("buildTarget/jvmCompileClasspath") -operation BuildTargetJvmCompileClasspath { - input: JvmCompileClasspathParams - output: JvmCompileClasspathResult -} - - -structure JvmCompileClasspathParams { - @required - targets: BuildTargetIdentifiers -} - -structure JvmCompileClasspathResult { - @required - items: JvmCompileClasspathItems -} - -structure JvmCompileClasspathItem { - @required - target: BuildTargetIdentifier - /// The dependency classpath for this target, must be - /// identical to what is passed as arguments to - /// the -classpath flag in the command line interface - /// of scalac. - @required - classpath: Classpath -} - -list JvmCompileClasspathItems { - member: JvmCompileClasspathItem -} - -/// `JvmSourceItemData` contains JVM-specific metadata for a source item. -structure JvmSourceItemData { - /// The package name associated with the source item. - /// - /// If the source item is a file, this value must match the package declaration within the file. - /// - /// If the source item is a directory, the package name can be empty if the directory is at the package root, - /// such as in a Maven structure (e.g., source directories like `src/main/java` and `src/test/java`). - /// In non-conventional directory structures, the package name for the directory should be set to the package prefix - /// that will be applied to all source files within the directory. - /// For example, if a source directory is `a`, containing a source file `a/b/Lib.java` - /// where the package name for `Lib` is `my.example.b`, - /// then the package prefix for the directory `a` should be set to `my.example`. - /// If a consistent package name cannot be applied to the source directory, - /// such as when each source file within the source directory has an arbitrary package name, - /// the package name for the source directory should be set to null. - packageName: String -} diff --git a/bspJsonRpc/smithy/scala.smithy b/bspJsonRpc/smithy/scala.smithy deleted file mode 100644 index dd1217f..0000000 --- a/bspJsonRpc/smithy/scala.smithy +++ /dev/null @@ -1,337 +0,0 @@ -$version: "2" - -namespace bsp.scalaext - -use bsp#Arguments -use bsp#BuildTargetData -use bsp#BuildTargetIdentifier -use bsp#BuildTargetIdentifiers -use bsp#DebugSessionParamsData -use bsp#DiagnosticData -use bsp#Range -use bsp#RunParamsData -use bsp#TestParamsData -use bsp#URIs -use bsp.jvmext#Classpath -use bsp.jvmext#JvmBuildTarget -use bsp.jvmext#JvmOptions -use jsonrpclib#jsonNotification -use jsonrpclib#jsonRPC -use jsonrpclib#jsonRequest - -@jsonRPC -service ScalaBuildServer { - operations: [ - BuildTargetScalacOptions, - BuildTargetScalaTestClasses, - BuildTargetScalaMainClasses, - ] -} - -/// `ScalaBuildTarget` is a basic data structure that contains scala-specific -/// metadata for compiling a target containing Scala sources. -structure ScalaBuildTarget { - /// The Scala organization that is used for a target. - @required - scalaOrganization: String - /// The scala version to compile this target - @required - scalaVersion: String - /// The binary version of scalaVersion. - /// For example, 2.12 if scalaVersion is 2.12.4. - @required - scalaBinaryVersion: String - /// The target platform for this target - @required - platform: ScalaPlatform - /// A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect. - @required - jars: URIs - /// The jvm build target describing jdk to be used - jvmBuildTarget: JvmBuildTarget -} - -intEnum ScalaPlatform { - JVM = 1 - JS = 2 - NATIVE = 3 -} - -/// `ScalaTestParams` contains scala-specific metadata for testing Scala targets. -structure ScalaTestParams { - /// The test classes to be run in this test execution. - /// It is the result of `buildTarget/scalaTestClasses`. - testClasses: ScalaTestClassesItems - /// The JVM options to run tests with. They replace any options - /// that are defined by the build server if defined. - jvmOptions: JvmOptions -} - -/// The build target scalac options request is sent from the client to the server to -/// query for the list of compiler options necessary to compile in a given list of -/// targets. -@jsonRequest("buildTarget/scalacOptions") -operation BuildTargetScalacOptions { - input: ScalacOptionsParams - output: ScalacOptionsResult -} - -structure ScalacOptionsParams { - @required - targets: BuildTargetIdentifiers -} - -structure ScalacOptionsResult { - @required - items: ScalacOptionsItems -} - -structure ScalacOptionsItem { - @required - target: BuildTargetIdentifier - /// Additional arguments to the compiler. - /// For example, -deprecation. - @required - options: ScalacOptionsList - /// The dependency classpath for this target, must be - /// identical to what is passed as arguments to - /// the -classpath flag in the command line interface - /// of scalac. - @required - @deprecated(message: "When the jvmCompileClasspath capability is supported, this might be empty and the buildTarget/jvmCompileClasspath endpoint should be used instead.") - classpath: Classpath - /// The output directory for classfiles produced by this target - @required - classDirectory: String -} - -list ScalacOptionsItems { - member: ScalacOptionsItem -} - -list ScalacOptionsList { - member: String -} - -/// The Scala build target test classes request is sent from the client to the -/// server to query for the list of fully qualified names of test classes in a given -/// list of targets. -/// -/// This method can for example be used by a client to: -/// -/// - Show a list of the discovered classes that can be tested. -/// - Attach a "Run test suite" button above the definition of a test suite via -/// `textDocument/codeLens`. -/// -/// (To render the code lens, the language server needs to map the fully qualified -/// names of the test targets to the defining source file via -/// `textDocument/definition`. Then, once users click on the button, the language -/// server can pass the fully qualified name of the test class as an argument to the -/// `buildTarget/test` request.) -/// -/// This request may trigger a compilation on the selected build targets. The server -/// is free to send any number of `build/task*`, `build/publishDiagnostics` and -/// `build/logMessage` notifications during compilation before completing the -/// response. -/// -/// The client will get a `originId` field in `ScalaTestClassesResult` if the -/// `originId` field in the `ScalaTestClassesParams` is defined. -@jsonRequest("buildTarget/scalaTestClasses") -@deprecated(message: "Use buildTarget/jvmTestEnvironment instead") -operation BuildTargetScalaTestClasses { - input: ScalaTestClassesParams - output: ScalaTestClassesResult -} - -structure ScalaTestClassesParams { - @required - targets: BuildTargetIdentifiers - /// An optional number uniquely identifying a client request. - originId: String -} - -structure ScalaTestClassesResult { - /// An optional id of the request that triggered this result. - @required - items: ScalaTestClassesItems -} - -list ScalaTestClassesItems { - member: ScalaTestClassesItem -} - -structure ScalaTestClassesItem { - /// The build target that contains the test classes. - @required - target: BuildTargetIdentifier - /// Name of the the framework to which classes belong. - /// It's optional in order to maintain compatibility, however it is expected - /// from the newer implementations to not leave that field unspecified. - framework: String - /// The fully qualified names of the test classes in this target - @required - classes: ScalaTestClassesList -} - -list ScalaTestClassesList { - member: String -} - -/// The build target main classes request is sent from the client to the server to -/// query for the list of main classes that can be fed as arguments to -/// `buildTarget/run`. This method can be used for the same use cases than the -/// [Scala Test Classes Request](#buildtargetscalatestclasses-request) enables. -/// This request may trigger a compilation on the selected build targets. The server -/// is free to send any number of `build/taskStart`, `build/taskProgress`, -/// `build/taskFinish`, `build/publishDiagnostics` and `build/logMessage` -/// notifications during compilation before completing the response. -/// The client will get a `originId` field in `ScalaMainClassesResult` if the -/// `originId` field in the `ScalaMainClassesParams` is defined. -@jsonRequest("buildTarget/scalaMainClasses") -@deprecated(message: "Use buildTarget/jvmRunEnvironment instead") -operation BuildTargetScalaMainClasses { - input: ScalaMainClassesParams - output: ScalaMainClassesResult -} - -structure ScalaMainClassesParams { - @required - targets: BuildTargetIdentifiers - /// An optional number uniquely identifying a client request. - originId: String -} - -structure ScalaMainClassesResult { - @required - items: ScalaMainClassesItems - /// An optional id of the request that triggered this result. - originId: String -} - -structure ScalaMainClassesItem { - /// The build target that contains the test classes. - @required - target: BuildTargetIdentifier - /// The main class item. - @required - classes: ScalaMainClassesList -} - -structure ScalaMainClass { - /// The main class to run. - @required - @jsonName("class") - className: String - /// The user arguments to the main entrypoint. - @required - @deprecated(message: "Use `buildTarget/run` params instead", since: "2.2.0") - arguments: Arguments - /// The jvm options for the application. - @required - jvmOptions: JvmOptions - /// The environment variables for the application. - @deprecated(message: "Use `buildTarget/run` params instead", since: "2.2.0") - environmentVariables: EnvironmentVariablesList -} - -list ScalaMainClassesList { - member: ScalaMainClass -} - -list ScalaMainClassesItems { - member: ScalaMainClassesItem -} - -list ScalaTestSuiteSelections { - member: ScalaTestSuiteSelection -} - -@deprecated(message: "Use `EnvironmentVariables` (a map) instead", since: "2.2.0") -list EnvironmentVariablesList { - member: String -} - -/// Each element of this array is a fully qualified class name. -list ScalaTestSuiteClasses { - member: String -} - -/// The debug session will connect to a running process. The DAP client will send the port of the running process later. -structure ScalaAttachRemote { -} - -structure ScalaTestSuites { - /// The fully qualified names of the test classes in this target and the tests in this test classes - @required - suites: ScalaTestSuiteSelections - /// Additional jvmOptions which will be passed to the forked JVM - @required - jvmOptions: JvmOptions - /// Enviroment variables should be an array of strings in format KEY=VALUE - @required - @deprecated(message: "Use `buildTarget/test` params instead", since: "2.2.0") - environmentVariables: EnvironmentVariablesList -} - -list ScalaTestSuiteSelectionTests { - member: String -} - -structure ScalaTestSuiteSelection { - /// Fully qualified name of the test suite class - @required - className: String // TODO: inconsistent, should be renamed to `class` in JSON - /// List of tests which should be run within this test suite. - /// Empty collection means that all of them are supposed to be executed. - @required - tests: ScalaTestSuiteSelectionTests -} - -/// `ScalaDiagnostic` is a data structure that contains Scala-specific -/// metadata generated by Scala compilation. -structure ScalaDiagnostic { - /// Actions (also known as quick fixes) that are able to either fix or address - /// the issue that is causing this diagnostic. - actions: ScalaActions -} - -/// A Scala action represents a change that can be performed in code. -/// See also [LSP: Code Action Request](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction). -/// -/// **Note**: In LSP, `CodeAction` appears only as a response to a `textDocument/codeAction` request, -/// whereas ScalaAction is intended to be returned as `Diagnostics.data.actions`. -structure ScalaAction { - /// A short, human-readable, title for this code action. - @required - title: String - /// A description that may be shown to the user client side to explain the action. - description: String - /// The workspace edit this code action performs. - edit: ScalaWorkspaceEdit -} - -list ScalaActions { - member: ScalaAction -} - -/// A workspace edit represents changes to many resources managed in the workspace. -structure ScalaWorkspaceEdit { - @required - changes: ScalaTextEdits -} - -/// A textual edit applicable to a text document. -structure ScalaTextEdit { - /// The range of the text document to be manipulated. To insert - /// text into a document create a range where start === end. - @required - range: Range - /// The string to be inserted. For delete operations use an - /// empty string. - @required - newText: String -} - -list ScalaTextEdits { - member: ScalaTextEdit -} diff --git a/build.sc b/build.sc index 657fef1..5d08736 100644 --- a/build.sc +++ b/build.sc @@ -4,7 +4,7 @@ import mill._ import mill.define.Sources import scalalib._ -import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.34` +import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.35` import _root_.smithy4s.codegen.mill._ trait CommonScalaModule extends ScalaModule { @@ -25,9 +25,11 @@ object sls extends CommonScalaModule { def mainClass = Some("org.scala.abusers.sls.SimpleScalaServer") def ivyDeps = Agg( - ivy"tech.neander::jsonrpclib-fs2::0.0.7+20-ba98e073-SNAPSHOT".forceVersion(), + ivy"co.fs2::fs2-io:3.13.0-M2", + ivy"tech.neander::jsonrpclib-fs2::0.0.7+18-0e7dd223-SNAPSHOT".forceVersion(), ivy"tech.neander::langoustine-app::0.0.22", ivy"com.lihaoyi::os-lib:0.11.4", + ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-d25359c-20250506T013346Z-SNAPSHOT", ) def scalacOptions = Seq( @@ -49,12 +51,10 @@ object bspJsonRpc extends CommonScalaModule with Smithy4sModule { ) def ivyDeps = Agg( - ivy"co.fs2::fs2-io:3.13.0-M2", - ivy"com.disneystreaming.smithy4s::smithy4s-json::${_root_.smithy4s.codegen.BuildInfo.version}", - ivy"tech.neander::jsonrpclib-smithy4s::0.0.7+20-ba98e073-SNAPSHOT", + ivy"com.disneystreaming.smithy4s::smithy4s-core::${_root_.smithy4s.codegen.BuildInfo.version}" ) override def smithy4sIvyDeps = Agg( - ivy"com.disneystreaming.alloy:alloy-core:0.3.19" + ivy"tech.neander:jsonrpclib-smithy:0.0.7+18-0e7dd223+20250506-0324-SNAPSHOT" ) } diff --git a/sls/src/org/scala/abusers/sls/BspClient.scala b/sls/src/org/scala/abusers/sls/BspClient.scala index 3d1708a..d0e65ff 100644 --- a/sls/src/org/scala/abusers/sls/BspClient.scala +++ b/sls/src/org/scala/abusers/sls/BspClient.scala @@ -2,19 +2,19 @@ package org.scala.abusers.sls import bsp.* import cats.effect.* +import cats.syntax.all.* import com.comcast.ip4s.* import fs2.io.* import fs2.io.net.Network import jsonrpclib.fs2.* -import jsonrpclib.smithy4sinterop.ClientStub +import smithy4sbsp.bsp4s.BSPCodecs def makeBspClient(path: String, channel: FS2Channel[IO], report: String => IO[Unit]): Resource[IO, BuildServer[IO]] = Network[IO] .connect(UnixSocketAddress(path)) .flatMap { socket => - Resource.make(for - client <- ClientStub(BuildServer, channel) - fiber <- fs2.Stream + BSPCodecs.clientStub(BuildServer, channel).toResource <* + fs2.Stream .eval(IO.never) .concurrently( socket.reads.through(lsp.decodeMessages).evalTap(m => report(m.toString)).through(channel.inputOrBounce) @@ -23,7 +23,5 @@ def makeBspClient(path: String, channel: FS2Channel[IO], report: String => IO[Un .compile .drain .guarantee(IO.consoleForIO.errorln("Terminating server")) - .start - yield (client, fiber)) { case (_, fiber) => fiber.cancel } + .background } - .map { case (client, _) => client } diff --git a/sls/src/org/scala/abusers/sls/DocumentSync.scala b/sls/src/org/scala/abusers/sls/DocumentSync.scala index fbab559..566ea15 100644 --- a/sls/src/org/scala/abusers/sls/DocumentSync.scala +++ b/sls/src/org/scala/abusers/sls/DocumentSync.scala @@ -1,11 +1,9 @@ package org.scala.abusers.sls // TODO package completions are still here when they should not, also we should get whole package completion out of the box import cats.effect.* -import cats.effect.std.Queue import cats.syntax.all.* import langoustine.lsp.aliases.TextDocumentContentChangeEvent import langoustine.lsp.structures.* -import langoustine.lsp.Communicate import langoustine.lsp.Invocation import java.net.URI diff --git a/sls/src/org/scala/abusers/sls/SimpleLanguageServer.scala b/sls/src/org/scala/abusers/sls/SimpleLanguageServer.scala index e0eb41d..dc8d441 100644 --- a/sls/src/org/scala/abusers/sls/SimpleLanguageServer.scala +++ b/sls/src/org/scala/abusers/sls/SimpleLanguageServer.scala @@ -53,7 +53,10 @@ object SimpleScalaServer extends LangoustineApp.Simple: state <- stateRef.get bloop = state.bloopConn.get.client targets <- bloop.workspaceBuildTargets() - targets0 = targets.targets.map(_.id) + targets0 = targets.targets + // todo: dispatch to all the targets or wait for smithy4s to add mixins even without @adt + .map(t => t.project.scala.getOrElse(sys.error(s"not a scala target: $t"))) + .map(_.id) // ourTarget <- targets.targets.find(in.params.textDocument.uri) result <- bloop.buildTargetCompile(targets0) _ <- logMessage(in.toClient, s"${result}") diff --git a/sls/test/src/org/scala/abusers/sls/DocumentSyncTests.scala b/sls/test/src/org/scala/abusers/sls/DocumentSyncTests.scala index 195ec81..b2b38b4 100644 --- a/sls/test/src/org/scala/abusers/sls/DocumentSyncTests.scala +++ b/sls/test/src/org/scala/abusers/sls/DocumentSyncTests.scala @@ -34,7 +34,7 @@ object TextDocumentSyncSuite extends SimpleIOSuite: val uri = DocumentUri("/home/Test.scala") val client = TestClient(log) for - mgr <- DocumentSyncManager.create + mgr <- DocumentSyncManager.instance _ <- mgr.didOpen(client.input(open(uri, "Hello!"))) _ <- mgr.didChange( @@ -62,7 +62,7 @@ object TextDocumentSyncSuite extends SimpleIOSuite: val uri = DocumentUri("/home/Test.scala") val client = TestClient(log) for - mgr <- DocumentSyncManager.create + mgr <- DocumentSyncManager.instance _ <- mgr.didOpen(client.input(open(uri, "val z = 3"))) _ <- mgr.didChange( @@ -86,7 +86,7 @@ object TextDocumentSyncSuite extends SimpleIOSuite: val uri = DocumentUri("/home/Test.scala") val client = TestClient(log) for - mgr <- DocumentSyncManager.create + mgr <- DocumentSyncManager.instance _ <- mgr.didOpen(client.input(open(uri, "val x = 1\nval y = 2"))) // full document replacement @@ -109,7 +109,7 @@ object TextDocumentSyncSuite extends SimpleIOSuite: val uri = DocumentUri("/home/Test.scala") val client = TestClient(log) for - mgr <- DocumentSyncManager.create + mgr <- DocumentSyncManager.instance _ <- mgr.didOpen(client.input(open(uri, "val x = 1\nval y = 2\nval z = 3"))) // full document replacement From fc04aa9d6d2b8d3e8911189dc0d4425794cd582d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Tue, 6 May 2025 04:00:03 +0200 Subject: [PATCH 2/4] bumps --- build.sc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sc b/build.sc index 5d08736..07ac34a 100644 --- a/build.sc +++ b/build.sc @@ -26,10 +26,10 @@ object sls extends CommonScalaModule { def ivyDeps = Agg( ivy"co.fs2::fs2-io:3.13.0-M2", - ivy"tech.neander::jsonrpclib-fs2::0.0.7+18-0e7dd223-SNAPSHOT".forceVersion(), + ivy"tech.neander::jsonrpclib-fs2::0.0.7+19-7d1323ce-SNAPSHOT".forceVersion(), ivy"tech.neander::langoustine-app::0.0.22", ivy"com.lihaoyi::os-lib:0.11.4", - ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-d25359c-20250506T013346Z-SNAPSHOT", + ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-6afb558-SNAPSHOT", ) def scalacOptions = Seq( @@ -55,6 +55,6 @@ object bspJsonRpc extends CommonScalaModule with Smithy4sModule { ) override def smithy4sIvyDeps = Agg( - ivy"tech.neander:jsonrpclib-smithy:0.0.7+18-0e7dd223+20250506-0324-SNAPSHOT" + ivy"tech.neander:jsonrpclib-smithy:0.0.7+19-7d1323ce-SNAPSHOT" ) } From d50f136eb1eec779e03ebbf7eda67525cffcc3f4 Mon Sep 17 00:00:00 2001 From: ghostbuster91 Date: Tue, 6 May 2025 23:45:42 +0200 Subject: [PATCH 3/4] cleanup --- .mill-version | 2 +- bspJsonRpc/smithy/spec.smithy | 45 ------------------- build.sc => build.mill | 23 +--------- sls/src/org/scala/abusers/sls/Server.scala | 51 ---------------------- 4 files changed, 3 insertions(+), 118 deletions(-) delete mode 100644 bspJsonRpc/smithy/spec.smithy rename build.sc => build.mill (58%) delete mode 100644 sls/src/org/scala/abusers/sls/Server.scala diff --git a/.mill-version b/.mill-version index 44ab23e..54dbed4 100644 --- a/.mill-version +++ b/.mill-version @@ -1 +1 @@ -0.11.13 +0.12.10 diff --git a/bspJsonRpc/smithy/spec.smithy b/bspJsonRpc/smithy/spec.smithy deleted file mode 100644 index 518c745..0000000 --- a/bspJsonRpc/smithy/spec.smithy +++ /dev/null @@ -1,45 +0,0 @@ -$version: "2.0" - -namespace test - -use jsonrpclib#jsonRequest -use jsonrpclib#jsonRPC -use jsonrpclib#jsonNotification - -@jsonRPC -service TestServer { - operations: [Greet, Ping] -} - -@jsonRPC -service TestClient { - operations: [Pong] -} - -@jsonRequest("greet") -operation Greet { - input := { - @required - name: String - } - output := { - @required - message: String - } -} - -@jsonNotification("ping") -operation Ping { - input := { - @required - ping: String - } -} - -@jsonNotification("pong") -operation Pong { - input := { - @required - pong: String - } -} diff --git a/build.sc b/build.mill similarity index 58% rename from build.sc rename to build.mill index 07ac34a..1f2128c 100644 --- a/build.sc +++ b/build.mill @@ -4,9 +4,6 @@ import mill._ import mill.define.Sources import scalalib._ -import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.35` -import _root_.smithy4s.codegen.mill._ - trait CommonScalaModule extends ScalaModule { override def repositoriesTask: Task[Seq[Repository]] = T.task { Seq( @@ -21,12 +18,11 @@ trait CommonScalaModule extends ScalaModule { object sls extends CommonScalaModule { - def moduleDeps = Seq(bspJsonRpc) - def mainClass = Some("org.scala.abusers.sls.SimpleScalaServer") + def mainClass = Some("org.scala.abusers.sls.SimpleScalaServer") def ivyDeps = Agg( ivy"co.fs2::fs2-io:3.13.0-M2", - ivy"tech.neander::jsonrpclib-fs2::0.0.7+19-7d1323ce-SNAPSHOT".forceVersion(), + ivy"tech.neander::jsonrpclib-fs2::0.0.8+20-8d37b4ca-SNAPSHOT".forceVersion(), ivy"tech.neander::langoustine-app::0.0.22", ivy"com.lihaoyi::os-lib:0.11.4", ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-6afb558-SNAPSHOT", @@ -43,18 +39,3 @@ object sls extends CommonScalaModule { def testFramework = "weaver.framework.CatsEffect" } } - -object bspJsonRpc extends CommonScalaModule with Smithy4sModule { - - def scalacOptions = Seq( - "-Wunused:all" - ) - - def ivyDeps = Agg( - ivy"com.disneystreaming.smithy4s::smithy4s-core::${_root_.smithy4s.codegen.BuildInfo.version}" - ) - - override def smithy4sIvyDeps = Agg( - ivy"tech.neander:jsonrpclib-smithy:0.0.7+19-7d1323ce-SNAPSHOT" - ) -} diff --git a/sls/src/org/scala/abusers/sls/Server.scala b/sls/src/org/scala/abusers/sls/Server.scala deleted file mode 100644 index 63017e6..0000000 --- a/sls/src/org/scala/abusers/sls/Server.scala +++ /dev/null @@ -1,51 +0,0 @@ -package examples.smithy.server - -import cats.effect.* -import cats.effect.std.Console -import cats.effect.Concurrent -import cats.syntax.all.* -import com.comcast.ip4s.* -import fs2.io.* -import fs2.io.net.Datagram -import fs2.io.net.Network -import fs2.io.net.Socket -import fs2.io.net.SocketGroup -import fs2.io.net.SocketOption -import fs2.text -import fs2.Stream -import jsonrpclib.fs2.* -import jsonrpclib.smithy4sinterop.ClientStub -import jsonrpclib.smithy4sinterop.ServerEndpoints -import jsonrpclib.CallId -import jsonrpclib.Endpoint -import test.* // smithy4s-generated package - -def client(path: String) = - val socket = Network[IO].connect(UnixSocketAddress(path)) - -object ServerMain extends IOApp.Simple: - - // Reserving a method for cancelation. - val cancelEndpoint = CancelTemplate.make[CallId]("$/cancel", identity, identity) - - // Implementing the generated interface - class ServerImpl(client: TestClient[IO]) extends TestServer[IO]: - def greet(name: String): IO[GreetOutput] = IO.pure(GreetOutput(s"Server says: hello $name !")) - - def ping(ping: String): IO[Unit] = client.pong(s"Returned to sender: $ping") - - def printErr(s: String): IO[Unit] = IO.consoleForIO.errorln(s) - - def run: IO[Unit] = - val run = for - channel <- FS2Channel[IO](cancelTemplate = Some(cancelEndpoint)) - testClient <- ClientStub.stream(TestClient, channel) - _ <- channel.withEndpointsStream(ServerEndpoints(new ServerImpl(testClient))) - _ <- fs2.Stream - .eval(IO.never) // running the server forever - .concurrently(stdin[IO](512).through(lsp.decodeMessages).through(channel.inputOrBounce)) - .concurrently(channel.output.through(lsp.encodeMessages).through(stdout[IO])) - yield {} - - // Using errorln as stdout is used by the RPC channel - printErr("Starting server") >> run.compile.drain.guarantee(printErr("Terminating server")) From 09f6dddf6978cb955d2634f13ee62ad2cc9cd30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Tue, 6 May 2025 23:58:07 +0200 Subject: [PATCH 4/4] use good artifact --- build.mill | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.mill b/build.mill index 1f2128c..65fee76 100644 --- a/build.mill +++ b/build.mill @@ -25,7 +25,7 @@ object sls extends CommonScalaModule { ivy"tech.neander::jsonrpclib-fs2::0.0.8+20-8d37b4ca-SNAPSHOT".forceVersion(), ivy"tech.neander::langoustine-app::0.0.22", ivy"com.lihaoyi::os-lib:0.11.4", - ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-6afb558-SNAPSHOT", + ivy"org.polyvariant.smithy4s-bsp::bsp4s:0.1-8c8935f-SNAPSHOT", ) def scalacOptions = Seq(