Skip to content

Commit

Permalink
feat: refactor PDV to get data directly from nxls & apply in intellij (
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxKless authored Sep 19, 2024
1 parent 25d2c79 commit bf2ad34
Show file tree
Hide file tree
Showing 40 changed files with 1,599 additions and 107 deletions.
3 changes: 3 additions & 0 deletions apps/intellij/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ dependencies {

implementation("io.github.z4kn4fein:semver:2.0.0")

implementation("io.github.nsk90:kstatemachine:0.31.0")
implementation("io.github.nsk90:kstatemachine-coroutines:0.31.0")

intellijPlatform {
intellijIdeaUltimate(providers.gradleProperty("platformVersion"))

Expand Down
17 changes: 12 additions & 5 deletions apps/intellij/src/main/kotlin/dev/nx/console/ProjectPostStartup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import dev.nx.console.telemetry.ExtensionLevelErrorTelemetry
import dev.nx.console.telemetry.TelemetryEvent
import dev.nx.console.telemetry.TelemetryService
import dev.nx.console.utils.Notifier
import dev.nx.console.utils.ProjectLevelCoroutineHolderService
import dev.nx.console.utils.nxBasePath
import dev.nx.console.utils.sync_services.NxProjectJsonToProjectMap
import dev.nx.console.utils.sync_services.NxVersionUtil
import java.io.File
import kotlinx.coroutines.launch

internal class ProjectPostStartup : ProjectActivity {
override suspend fun execute(project: Project) {
Expand All @@ -21,11 +24,15 @@ internal class ProjectPostStartup : ProjectActivity {

while (true) {
if (filesToScanFor.any { currentDir.resolve(it).exists() }) {
val service = NxlsService.getInstance(project)
service.start()
service.runAfterStarted {
NxProjectJsonToProjectMap.getInstance(project).init()
ProjectGraphErrorProblemProvider.getInstance(project).init()
ProjectLevelCoroutineHolderService.getInstance(project).cs.launch {
val service = NxlsService.getInstance(project)

service.start()
service.runAfterStarted {
NxProjectJsonToProjectMap.getInstance(project).init()
ProjectGraphErrorProblemProvider.getInstance(project).init()
NxVersionUtil.getInstance(project).listen()
}
}
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.intellij.ui.jcef.*
import dev.nx.console.models.NxError
import dev.nx.console.nxls.NxWorkspaceRefreshListener
import dev.nx.console.nxls.NxlsService
import dev.nx.console.project_details.ProjectDetailsBrowser
import dev.nx.console.project_details.browsers.OldProjectDetailsBrowser
import dev.nx.console.utils.executeJavascriptWithCatch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand Down Expand Up @@ -41,10 +41,10 @@ class NxGraphBrowser(project: Project) : NxGraphBrowserBase(project) {
try {
refresh()
} catch (e: Throwable) {
logger<ProjectDetailsBrowser>().debug(e.message)
logger<OldProjectDetailsBrowser>().debug(e.message)
}
}
}
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ import dev.nx.console.utils.nxBasePath
import java.io.File
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

@Service(Service.Level.PROJECT)
class ProjectGraphErrorProblemProvider(val project: Project, val cs: CoroutineScope) {
private val nxProblemsProvider = NxProblemsProvider(project)
private val problemsCollector = ProblemsCollector.getInstance(project)

val mutex = Mutex()

private val problems = mutableListOf<Problem>()

fun init() {
Expand All @@ -45,8 +49,11 @@ class ProjectGraphErrorProblemProvider(val project: Project, val cs: CoroutineSc

problems.forEach { problemsCollector.problemDisappeared(it) }
newProblems?.forEach { problemsCollector.problemAppeared(it) }
problems.clear()
problems.addAll(newProblems ?: emptyList())

mutex.withLock {
problems.clear()
problems.addAll(newProblems ?: emptyList())
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions apps/intellij/src/main/kotlin/dev/nx/console/models/NxPDVData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.nx.console.models

data class NxPDVData(
val resultType: String,
val graphBasePath: String?,
val pdvDataSerialized: String?,
val pdvDataSerializedMulti: Map<String, String>?,
val errorsSerialized: String?,
val errorMessage: String?,
) {
init {
require(
resultType == "SUCCESS" ||
resultType == "SUCCESS_MULTI" ||
resultType == "ERROR" ||
resultType == "NO_GRAPH_ERROR" ||
resultType == "OLD_NX_VERSION"
) {
"resultType must be of known type"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ data class NxProject(
val targets: Map<String, NxTarget>,
val sourceRoot: String?,
val projectType: String,
val metadata: NxProjectMetadata?
val metadata: NxProjectMetadata?,
) {
init {
require(projectType == "application" || projectType == "library")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package dev.nx.console.models

import kotlinx.serialization.Serializable

data class NxTarget(
val executor: String,
val configurations: Map<String, Any>?,
val metadata: NxTargetMetadata?
val metadata: NxTargetMetadata?,
) {}

@Serializable()
data class NxTargetMetadata(
val description: String?,
val technologies: Array<String>?,
val nonAtomizedTarget: String?
val nonAtomizedTarget: String?,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
10 changes: 10 additions & 0 deletions apps/intellij/src/main/kotlin/dev/nx/console/models/NxVersion.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
package dev.nx.console.models

import com.intellij.util.text.SemVer
import kotlinx.serialization.Serializable

@Serializable()
data class NxVersion(val minor: Int, val major: Int, val full: String) {
public fun gte(other: NxVersion): Boolean {
val semVerThis = SemVer.parseFromText(this.full)
val semVerOther = SemVer.parseFromText(other.full)
if (semVerThis != null && semVerOther != null) {
return semVerThis >= semVerOther
}
if (this.major > other.major) {
return true
} else if (this.major == other.major) {
return this.minor >= other.minor
}
return false
}

fun equals(other: NxVersion): Boolean {
return this.major == other.major && this.minor == other.minor && this.full == other.full
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package dev.nx.console.models

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*

data class NxWorkspace(
val validWorkspaceJson: Boolean,
val workspace: NxWorkspaceConfiguration,
Expand All @@ -11,7 +14,7 @@ data class NxWorkspace(
val isEncapsulatedNx: Boolean,
val isPartial: Boolean?,
val workspaceLayout: WorkspaceLayout?,
val cloudStatus: NxCloudStatus?
val cloudStatus: NxCloudStatus?,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down Expand Up @@ -51,15 +54,18 @@ data class NxWorkspace(

data class WorkspaceLayout(val appsDir: String?, val libsDir: String?)

data class NxWorkspaceConfiguration(val projects: Map<String, NxProject>) {}
data class NxWorkspaceConfiguration(val projects: Map<String, NxProject>
// val sourceMaps: Map<String, Map<String, SourceInformation>>?,
) {}

@Serializable()
data class NxError(
val message: String?,
val name: String?,
val stack: String?,
val file: String?,
val pluginName: String?,
val cause: Any?
@Transient() val cause: Any? = null,
) {

constructor(message: String) : this(message, null, null, null, null, null)
Expand Down
38 changes: 32 additions & 6 deletions apps/intellij/src/main/kotlin/dev/nx/console/nxls/NxlsService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import org.eclipse.lsp4j.jsonrpc.MessageIssueException
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException

@Service(Service.Level.PROJECT)
class NxlsService(val project: Project, private val cs: CoroutineScope) {
class NxlsService(private val project: Project, private val cs: CoroutineScope) {
private var wrapper: NxlsWrapper = NxlsWrapper(project, cs)

private fun client(): NxlsLanguageClient? {
Expand Down Expand Up @@ -50,6 +50,13 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {
project.messageBus.syncPublisher(NX_WORKSPACE_REFRESH_TOPIC).onNxWorkspaceRefresh()
}
}
client()?.registerRefreshStartedCallback {
cs.launch {
project.messageBus
.syncPublisher(NX_WORKSPACE_REFRESH_STARTED_TOPIC)
.onWorkspaceRefreshStarted()
}
}
}

suspend fun close() {
Expand Down Expand Up @@ -78,6 +85,12 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {
}()
}

suspend fun workspaceSerialized(): String? {
return withMessageIssueCatch("nx/workspaceSerialized") {
server()?.getNxService()?.workspaceSerialized()?.await()
}()
}

suspend fun generators(): List<NxGenerator> {
return withMessageIssueCatch("nx/generators") {
server()?.getNxService()?.generators()?.await()
Expand All @@ -97,7 +110,7 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {

suspend fun generatorContextFromPath(
generator: NxGenerator? = null,
path: String?
path: String?,
): NxGeneratorContext? {
return withMessageIssueCatch("nx/generatorContextV2") {
val request = NxGetGeneratorContextFromPathRequest(path)
Expand Down Expand Up @@ -165,16 +178,16 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {
}()
}

suspend fun sourceMapFilesToProjectMap(): Map<String, String> {
suspend fun sourceMapFilesToProjectsMap(): Map<String, Array<String>> {
return withMessageIssueCatch("nx/sourceMapFilesToProjectMap") {
server()?.getNxService()?.sourceMapFilesToProjectMap()?.await()
server()?.getNxService()?.sourceMapFilesToProjectsMap()?.await()
}()
?: emptyMap()
}

suspend fun targetsForConfigFile(
projectName: String,
configFilePath: String
configFilePath: String,
): Map<String, NxTarget> {
return withMessageIssueCatch("nx/targetsForConfigFile") {
val request = NxTargetsForConfigFileRequest(projectName, configFilePath)
Expand All @@ -189,6 +202,12 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {
}()
}

suspend fun pdvData(filePath: String): NxPDVData? {
return withMessageIssueCatch("nx/pdvData") {
server()?.getNxService()?.pdvData(PDVDataRequest(filePath))?.await()
}()
}

fun addDocument(editor: Editor) {
wrapper.connect(editor)
}
Expand All @@ -215,7 +234,7 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {

private fun <T> withMessageIssueCatch(
requestName: String,
block: suspend () -> T
block: suspend () -> T,
): suspend () -> T? {
return {
try {
Expand All @@ -234,9 +253,16 @@ class NxlsService(val project: Project, private val cs: CoroutineScope) {

val NX_WORKSPACE_REFRESH_TOPIC: Topic<NxWorkspaceRefreshListener> =
Topic("NxWorkspaceRefresh", NxWorkspaceRefreshListener::class.java)

val NX_WORKSPACE_REFRESH_STARTED_TOPIC: Topic<NxWorkspaceRefreshStartedListener> =
Topic("NxWorkspaceRefreshStarted", NxWorkspaceRefreshStartedListener::class.java)
}
}

fun interface NxWorkspaceRefreshListener {
fun onNxWorkspaceRefresh()
}

fun interface NxWorkspaceRefreshStartedListener {
fun onWorkspaceRefreshStarted()
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ class NxlsWrapper(val project: Project, private val cs: CoroutineScope) {
NxGeneratorOption::class.java,
NxGeneratorOptionDeserializer(),
)
// gson.registerTypeAdapter(
// SourceInformation::class.java,
// SourceInformationDeserializer(),
// )
},
)
.also {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ private val log = logger<NxlsLanguageClient>()
class NxlsLanguageClient : LanguageClient {

val refreshCallbacks: MutableList<() -> Unit> = mutableListOf()
val refreshStartedCallback: MutableList<() -> Unit> = mutableListOf()

override fun telemetryEvent(`object`: Any?) {
TODO("Not yet implemented")
Expand Down Expand Up @@ -41,9 +42,19 @@ class NxlsLanguageClient : LanguageClient {
refreshCallbacks.add(block)
}

fun registerRefreshStartedCallback(block: () -> Unit) {
refreshStartedCallback.add(block)
}

@JsonNotification("nx/refreshWorkspace")
fun refreshWorkspace() {
log.info("Refresh workspace called from nxls")
refreshCallbacks.forEach { it() }
}

@JsonNotification("nx/refreshWorkspaceStarted")
fun refreshWorkspaceStarted() {
log.info("Refresh workspace started called from nxls")
refreshStartedCallback.forEach { it() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ interface NxService {
throw UnsupportedOperationException()
}

@JsonRequest
fun workspaceSerialized(
workspaceRequest: NxWorkspaceRequest = NxWorkspaceRequest()
): CompletableFuture<String> {
throw UnsupportedOperationException()
}

@JsonRequest
fun generators(
generatorsRequest: NxGeneratorsRequest = NxGeneratorsRequest()
Expand Down Expand Up @@ -87,7 +94,7 @@ interface NxService {
}

@JsonRequest
fun sourceMapFilesToProjectMap(): CompletableFuture<Map<String, String>> {
fun sourceMapFilesToProjectsMap(): CompletableFuture<Map<String, Array<String>>> {
throw UnsupportedOperationException()
}

Expand Down Expand Up @@ -117,4 +124,9 @@ interface NxService {
fun cloudStatus(): CompletableFuture<NxCloudStatus> {
throw UnsupportedOperationException()
}

@JsonRequest
fun pdvData(pdvDataRequest: PDVDataRequest): CompletableFuture<NxPDVData> {
throw UnsupportedOperationException()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dev.nx.console.nxls.server.requests

data class PDVDataRequest(val filePath: String)
Loading

0 comments on commit bf2ad34

Please sign in to comment.