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

GH-2 Migrated to LSP4IJ client #3

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .run/Package plugin.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

SPDX-License-Identifier: EPL-2.0

Copyright IBA Group 2024
Copyright Contributors to the Zowe Project
-->

<component name="ProjectRunConfigurationManager">
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# COBOL Language Support plug-in for IntelliJ IDEA™

Provides:
- syntax highlighting support using TextMate bundle from [eclipse-che4z/che-che4z-lsp-for-cobol](https://github.com/eclipse-che4z/che-che4z-lsp-for-cobol) by Broadcom®
- code actions using LSP technology with client from [ballerina-platform/lsp4intellij](https://github.com/ballerina-platform/lsp4intellij) and server from [eclipse-che4z/che-che4z-lsp-for-cobol](https://github.com/eclipse-che4z/che-che4z-lsp-for-cobol) by Broadcom®
- syntax highlighting support using TextMate bundle from [eclipse-che4z/che-che4z-lsp-for-cobol](https://github.com/eclipse-che4z/che-che4z-lsp-for-cobol)
- code actions using LSP technology with client from [redhat-developer/lsp4ij](https://github.com/redhat-developer/lsp4ij) and server from [eclipse-che4z/che-che4z-lsp-for-cobol](https://github.com/eclipse-che4z/che-che4z-lsp-for-cobol)

## Prerequisites

- Java v17
- IntelliJ v2023.2

## How to run (user)

- Open the folder with the project, run `./gradlew buildPlugin` (for Unix-like) or `.\gradlew.bat buildPlugin` (for Windows) to build the plugin (or run "Package plugin" configuration)
- The built plug-in will be at the `build/distributions` in .zip format, install it with Settings -> Plugins -> Install plugin from disk
- Reload your IDE

## How to run (developer)

- Open the folder with the project, run "Run plugin" configuration, wait for the other instance of IDE to run
17 changes: 5 additions & 12 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2024
* Copyright Contributors to the Zowe Project
*/

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
Expand All @@ -23,23 +23,16 @@ version = properties("pluginVersion").get()

repositories {
mavenCentral()
maven {
url = uri("https://jitpack.io") // lsp4intellij
}
}

dependencies {
// TODO: update the dependency to fix the issues asap
// CVE-2023-2976 - no impact on the project (25.04.2024)
// CVE-2020-8908 - no impact on the project (25.04.2024)
implementation("com.github.ballerina-platform:lsp4intellij:0.96.0")
}

// Configure Gradle IntelliJ Plugin
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
intellij {
version.set(properties("platformVersion").get())
plugins.set(listOf("org.jetbrains.plugins.textmate"))
// pluginsRepositories {
// custom("https://plugins.jetbrains.com/plugins/nightly/23257")
// }
plugins.set(listOf("org.jetbrains.plugins.textmate", "com.redhat.devtools.lsp4ij:0.0.1"))
}

tasks {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ pluginVersion = 0.0.1
pluginGroup = org.zowe

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 241
pluginSinceBuild = 232
pluginUntilBuild = 241.*
32 changes: 0 additions & 32 deletions src/main/kotlin/org/zowe/cobol/init/CobolPluginListener.kt

This file was deleted.

70 changes: 31 additions & 39 deletions src/main/kotlin/org/zowe/cobol/init/CobolPluginState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2024
* Copyright Contributors to the Zowe Project
*/

package org.zowe.cobol.init
Expand All @@ -16,16 +16,16 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.util.io.ZipUtil
import com.jetbrains.rd.util.firstOrNull
import org.zowe.cobol.lsp.CobolLSPExtensionManager
import org.zowe.cobol.lsp.CobolServerDefinition
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.plugins.textmate.TextMateService
import org.jetbrains.plugins.textmate.configuration.TextMateUserBundlesSettings
import org.jetbrains.plugins.textmate.plist.JsonPlistReader
import org.wso2.lsp4intellij.IntellijLanguageClient
import org.wso2.lsp4intellij.utils.FileUtils
import com.intellij.openapi.util.io.FileUtil
import com.redhat.devtools.lsp4ij.client.LanguageClientImpl
import com.redhat.devtools.lsp4ij.server.JavaProcessCommandBuilder
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider
import org.zowe.cobol.lsp.CobolLanguageClient
import java.nio.file.Path
import kotlin.io.path.exists
import kotlin.io.path.pathString
Expand Down Expand Up @@ -87,7 +87,7 @@ class CobolPluginState private constructor() : Disposable {
*/
@InitializationOnly
suspend fun unpackVSIX() {
if (currState != InitStates.DOWN) throw IllegalStateException("Invalid plug-in state. Expected: ${InitStates.DOWN}, current: $currState")
// if (currState != InitStates.DOWN) throw IllegalStateException("Invalid plug-in state. Expected: ${InitStates.DOWN}, current: $currState")
val doPathsAlreadyExist = computeVSIXPlacingPaths()
if (!doPathsAlreadyExist) {
val activeClassLoader = this::class.java.classLoader
Expand Down Expand Up @@ -116,8 +116,8 @@ class CobolPluginState private constructor() : Disposable {
* loaded to the IDE stays there
*/
@InitializationOnly
fun loadTextMateBundle() {
if (currState < InitStates.VSIX_UNPACKED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.VSIX_UNPACKED}, current: $currState")
fun loadLanguageClientDefinition(project: Project): LanguageClientImpl {
// if (currState < InitStates.VSIX_UNPACKED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.VSIX_UNPACKED}, current: $currState")
currState = InitStates.TEXTMATE_BUNDLE_LOAD_TRIGGERED
val emptyBundleName = "$TEXTMATE_BUNDLE_NAME-0.0.0"
val newBundleName = "$TEXTMATE_BUNDLE_NAME-$VSIX_VERSION"
Expand All @@ -133,6 +133,7 @@ class CobolPluginState private constructor() : Disposable {
TextMateService.getInstance().reloadEnabledBundles()
}
currState = InitStates.TEXTMATE_BUNDLE_LOADED
return CobolLanguageClient(project)
}

/** Extract COBOL language extensions, supported for recognition, from package.json in resources */
Expand Down Expand Up @@ -176,35 +177,25 @@ class CobolPluginState private constructor() : Disposable {
return cobolExtensions
}

/** Initialize LSP server and client, setup their communication. Will get the server.jar from the unzipped .vsix */
/** Initialize language server definition. Will run the LSP server command */
@InitializationOnly
fun loadLSP() {
if (currState < InitStates.VSIX_UNPACKED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.VSIX_UNPACKED}, current: $currState")
fun loadLanguageServerDefinition(project: Project): ProcessStreamConnectionProvider {
// if (currState < InitStates.VSIX_UNPACKED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.VSIX_UNPACKED}, current: $currState")
currState = InitStates.LSP_LOAD_TRIGGERED
val lspServerPathString = lspServerPath.pathString
val extensions = extractExtensionsFromPackageJson()
val manager = CobolLSPExtensionManager()

IntellijLanguageClient
.addServerDefinition(
CobolServerDefinition(
extensions.joinToString(","),
arrayOf(
"java",
"-jar",
"\"$lspServerPathString\"",
"pipeEnabled"
)
)
)
extensions.forEach { extension -> IntellijLanguageClient.addExtensionManager(extension, manager) }
// val extensions = extractExtensionsFromPackageJson()
val commands: MutableList<String> = JavaProcessCommandBuilder(project, "cobol")
.setJar(lspServerPathString)
.create()
commands.add("pipeEnabled")
currState = InitStates.LSP_LOADED
return object : ProcessStreamConnectionProvider(commands) {}
}

/** Initialization final step, no direct purposes for now */
@InitializationOnly
fun finishInitialization(project: Project) {
if (currState < InitStates.LSP_LOADED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.LSP_LOADED}, current: $currState")
if (currState != InitStates.LSP_LOADED || currState != InitStates.TEXTMATE_BUNDLE_LOADED) throw IllegalStateException("Invalid plug-in state. Expected: at least ${InitStates.LSP_LOADED}, current: $currState")
stateProject = project
currState = InitStates.UP
}
Expand All @@ -221,16 +212,17 @@ class CobolPluginState private constructor() : Disposable {
currState = InitStates.TEXTMATE_BUNDLE_UNLOADED
}

/** Disable LSP server wrappers together with LSP servers for the project before the plug-in's state is disposed */
@InitializationOnly
fun disableLSP() {
if (currState > InitStates.TEXTMATE_BUNDLE_UNLOADED) throw IllegalStateException("Invalid plug-in state. Expected: at most ${InitStates.TEXTMATE_BUNDLE_UNLOADED}, current: $currState")
currState = InitStates.LSP_UNLOAD_TRIGGERED
val projectPath = FileUtils.projectToUri(stateProject)
val serverWrappers = IntellijLanguageClient.getAllServerWrappersFor(projectPath)
serverWrappers.forEach { it.stop(true) }
currState = InitStates.LSP_UNLOADED
}
// TODO: finish, doc
// /** Disable LSP server wrappers together with LSP servers for the project before the plug-in's state is disposed */
// @InitializationOnly
// fun disableLSP() {
// if (currState > InitStates.TEXTMATE_BUNDLE_UNLOADED) throw IllegalStateException("Invalid plug-in state. Expected: at most ${InitStates.TEXTMATE_BUNDLE_UNLOADED}, current: $currState")
// currState = InitStates.LSP_UNLOAD_TRIGGERED
// val projectPath = FileUtils.projectToUri(stateProject)
// val serverWrappers = IntellijLanguageClient.getAllServerWrappersFor(projectPath)
// serverWrappers.forEach { it.stop(true) }
// currState = InitStates.LSP_UNLOADED
// }

/** Deinitialization final step, disposing purposes */
@InitializationOnly
Expand All @@ -243,4 +235,4 @@ class CobolPluginState private constructor() : Disposable {
override fun dispose() {
Disposer.dispose(this)
}
}
}
29 changes: 0 additions & 29 deletions src/main/kotlin/org/zowe/cobol/init/CobolStartupActivity.kt

This file was deleted.

4 changes: 2 additions & 2 deletions src/main/kotlin/org/zowe/cobol/init/InitStates.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2024
* Copyright Contributors to the Zowe Project
*/

package org.zowe.cobol.init
Expand All @@ -24,4 +24,4 @@ enum class InitStates {
LSP_LOAD_TRIGGERED,
LSP_LOADED,
UP
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/org/zowe/cobol/init/InitializationOnly.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2024
* Copyright Contributors to the Zowe Project
*/

package org.zowe.cobol.init
Expand Down
Loading