diff --git a/EmmyLua-Common/src/main/ext/com/tang/lsp/workspace.kt b/EmmyLua-Common/src/main/ext/com/tang/lsp/workspace.kt index f8bb1f7..41fd34f 100644 --- a/EmmyLua-Common/src/main/ext/com/tang/lsp/workspace.kt +++ b/EmmyLua-Common/src/main/ext/com/tang/lsp/workspace.kt @@ -53,6 +53,5 @@ interface ILuaFile : IVirtualFile { fun didChange(params: DidChangeTextDocumentParams) fun getPosition(line:Int, char: Int): Int fun processWords(processor: (w: Word) -> Boolean) - fun getVersion(): Int fun lock(code: () -> Unit) } \ No newline at end of file diff --git a/EmmyLua-Common/src/main/java/com/tang/intellij/lua/ty/TySubstitutor.kt b/EmmyLua-Common/src/main/java/com/tang/intellij/lua/ty/TySubstitutor.kt index 45c7b32..27a3da1 100644 --- a/EmmyLua-Common/src/main/java/com/tang/intellij/lua/ty/TySubstitutor.kt +++ b/EmmyLua-Common/src/main/java/com/tang/intellij/lua/ty/TySubstitutor.kt @@ -32,7 +32,7 @@ interface ITySubstitutor { class GenericAnalyzer(arg: ITy, private val par: ITy) : TyVisitor() { var cur: ITy = arg - var map:MutableMap? = null + var map: MutableMap? = null fun analyze(result: MutableMap) { map = result @@ -86,7 +86,7 @@ class GenericAnalyzer(arg: ITy, private val par: ITy) : TyVisitor() { warp(arg.returnTy) { par.returnTy.accept(this) } } - private fun warp(ty:ITy, action: () -> Unit) { + private fun warp(ty: ITy, action: () -> Unit) { if (Ty.isInvalid(ty)) return val arg = cur @@ -108,13 +108,18 @@ open class TySubstitutor : ITySubstitutor { } override fun substitute(function: ITyFunction): ITy { - return TySerializedFunction(function.mainSignature.substitute(this), - function.signatures.map { it.substitute(this) }.toTypedArray(), - function.flags) + return TySerializedFunction( + function.mainSignature.substitute(this), + function.signatures.map { it.substitute(this) }.toTypedArray(), + function.flags + ) } } +// cppcxy: 我对这里的递归爆栈感到绝望 class TyAliasSubstitutor private constructor(val project: Project) : ITySubstitutor { + val walkedClassName = mutableSetOf() + companion object { fun substitute(ty: ITy, context: SearchContext): ITy { /*if (context.forStub) @@ -124,12 +129,18 @@ class TyAliasSubstitutor private constructor(val project: Project) : ITySubstitu } override fun substitute(function: ITyFunction): ITy { - return TySerializedFunction(function.mainSignature.substitute(this), - function.signatures.map { it.substitute(this) }.toTypedArray(), - function.flags) + return TySerializedFunction( + function.mainSignature.substitute(this), + function.signatures.map { it.substitute(this) }.toTypedArray(), + function.flags + ) } override fun substitute(clazz: ITyClass): ITy { + if (clazz.className in this.walkedClassName) { + return clazz + } + this.walkedClassName.add(clazz.className) return clazz.recoverAlias(SearchContext.get(project), this) } diff --git a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaLanguageClient.kt b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaLanguageClient.kt index a41a3ef..fc31a67 100644 --- a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaLanguageClient.kt +++ b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaLanguageClient.kt @@ -16,6 +16,9 @@ interface LuaLanguageClient : LanguageClient { @JsonNotification("emmy/progressReport") fun progressReport(report: ProgressReport) + @JsonNotification("emmy/setServerStatus") + fun setServerStatus(status: ServerStatusParams) + @JsonNotification("emmy/reportAPI") fun reportAPI(params: LuaReportApiParams) } \ No newline at end of file diff --git a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaWorkspaceService.kt b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaWorkspaceService.kt index 4ef18f4..576c885 100644 --- a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaWorkspaceService.kt +++ b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaWorkspaceService.kt @@ -77,6 +77,7 @@ class LuaWorkspaceService : WorkspaceService, IWorkspace { removeFile(change.uri) addFile(change.uri) } + else -> {} } } @@ -290,15 +291,27 @@ class LuaWorkspaceService : WorkspaceService, IWorkspace { fun loadWorkspace() { cleanWorkspace() loadWorkspace(object : IProgressMonitor { - override fun done() { + override fun start() { if (VSCodeSettings.isVSCode) + client?.setServerStatus(ServerStatusParams("ok", "load workspace", true)) + } + + override fun done() { + if (VSCodeSettings.isVSCode) { client?.progressReport(ProgressReport("Finished!", 1f)) + client?.setServerStatus(ServerStatusParams("ok", "EmmyLua Language Server", false)) + } } override fun setProgress(text: String, percent: Float) { if (VSCodeSettings.isVSCode) client?.progressReport(ProgressReport(text, percent)) } + + override fun reportError(text: String) { + if (VSCodeSettings.isVSCode) + client?.setServerStatus(ServerStatusParams("error", "load fail", false)) + } }) } @@ -318,6 +331,7 @@ class LuaWorkspaceService : WorkspaceService, IWorkspace { private fun loadWorkspace(monitor: IProgressMonitor) { try { + monitor.start(); monitor.setProgress("load workspace folders", 0f) val collections = fileManager.findAllFiles() var totalFileCount = 0f @@ -330,7 +344,7 @@ class LuaWorkspaceService : WorkspaceService, IWorkspace { val file = uri.toFile() if (file != null) { monitor.setProgress( - "Emmy parse file[${(processedCount / totalFileCount * 100).toInt()}%]: ${file.name}", + "indexing ${processedCount.toInt()} / ${totalFileCount.toInt()} (${file.name})", processedCount / totalFileCount ) } @@ -338,7 +352,7 @@ class LuaWorkspaceService : WorkspaceService, IWorkspace { } } } catch (e: Exception) { - System.err.println("workspace parse error: $e") + monitor.reportError("workspace parse error: $e") } monitor.done() diff --git a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/ProgressMonitor.kt b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/ProgressMonitor.kt index c7f3c91..320e338 100644 --- a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/ProgressMonitor.kt +++ b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/ProgressMonitor.kt @@ -1,6 +1,8 @@ package com.tang.vscode interface IProgressMonitor { + fun start() fun setProgress(text: String, percent: Float) + fun reportError(text: String) fun done() } \ No newline at end of file diff --git a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/api/impl/LuaFile.kt b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/api/impl/LuaFile.kt index 20a5417..49c89c1 100644 --- a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/api/impl/LuaFile.kt +++ b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/api/impl/LuaFile.kt @@ -38,12 +38,9 @@ class LuaFile(override val uri: FileURI) : VirtualFileBase(uri), ILuaFile, Virtu private var _lines = mutableListOf() private var _myPsi: LuaPsiFile? = null private var _words: List? = null - private var _version: Int = 0 private var _rwl = ReentrantReadWriteLock() private var _isOpen = false - var workspaceDiagnosticResultId: String? = null - override fun didChange(params: DidChangeTextDocumentParams) { _rwl.write { if (params.contentChanges.isEmpty()) @@ -120,7 +117,6 @@ class LuaFile(override val uri: FileURI) : VirtualFileBase(uri), ILuaFile, Virtu } private fun onChanged() { - ++_version updateLines() doParser() } @@ -142,7 +138,6 @@ class LuaFile(override val uri: FileURI) : VirtualFileBase(uri), ILuaFile, Virtu index() } - /*private fun getLineStart(line: Int): Int { return _lines.firstOrNull { it.line == line } ?.startOffset ?: 0 }*/ @@ -188,10 +183,6 @@ class LuaFile(override val uri: FileURI) : VirtualFileBase(uri), ILuaFile, Virtu return pos } - override fun getVersion(): Int { - return _version - } - override fun lock(code: () -> Unit) { _rwl.read { code() diff --git a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/rpc.kt b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/rpc.kt index 9d50248..c7658ac 100644 --- a/EmmyLua-LS/src/main/kotlin/com/tang/vscode/rpc.kt +++ b/EmmyLua-LS/src/main/kotlin/com/tang/vscode/rpc.kt @@ -23,6 +23,13 @@ data class Annotator(val uri: String, val ranges: List, val type: A data class ProgressReport(val text: String, val percent: Float) +data class ServerStatusParams( + val health: String, + val message: String = "", + val loading: Boolean = false, + val command: String? = null, +) + enum class UpdateType { Created, Changed, @@ -49,13 +56,15 @@ data class EmmyConfigurationSource(val uri: String, val workspace: String) { } } - val fileURI: FileURI get() { - return FileURI.uri(uri, false) - } + val fileURI: FileURI + get() { + return FileURI.uri(uri, false) + } - val workspaceURI: FileURI get() { - return FileURI.uri(workspace, true) - } + val workspaceURI: FileURI + get() { + return FileURI.uri(workspace, true) + } override fun equals(other: Any?): Boolean { return other is EmmyConfigurationSource && other.uri == uri