Skip to content

Commit bc85420

Browse files
committed
初步支持扩展API,微调hover
1 parent adc9618 commit bc85420

File tree

11 files changed

+451
-36
lines changed

11 files changed

+451
-36
lines changed

EmmyLua-Common/src/main/ext/com/tang/intellij/lua/editor/completion/LookupElementFactory.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.tang.intellij.lua.ty.IFunSignature
1313
import com.tang.intellij.lua.ty.ITy
1414
import com.tang.intellij.lua.ty.ITyFunction
1515
import com.tang.intellij.lua.ty.hasVarargs
16+
import com.tang.lsp.ExtendApiBase
1617
import com.tang.lsp.ILuaFile
1718
import org.eclipse.lsp4j.CompletionItemKind
1819
import javax.swing.Icon
@@ -66,7 +67,10 @@ object LookupElementFactory {
6667
val file = classMember.containingFile?.virtualFile as? ILuaFile
6768
if (file != null) {
6869
item.data = "${file.uri}|${classMember.textOffset}"
70+
} else if (classMember is ExtendApiBase) {
71+
item.data = "extendApi|${clazzName}|${classMember.name}"
6972
}
73+
7074
if (classMember.isDeprecated) {
7175
item.deprecated = true
7276
}
@@ -90,6 +94,8 @@ object LookupElementFactory {
9094
val file = classMember.containingFile?.virtualFile as? ILuaFile
9195
if (file != null) {
9296
item.data = "${file.uri}|${classMember.textOffset}"
97+
} else if (classMember is ExtendApiBase) {
98+
item.data = "extendApi|${clazzName}|${classMember.name}"
9399
}
94100
if (classMember.isDeprecated) {
95101
item.deprecated = true
@@ -111,6 +117,8 @@ object LookupElementFactory {
111117
val file = field.containingFile?.virtualFile as? ILuaFile
112118
if (file != null) {
113119
element.data = "${file.uri}|${field.textOffset}"
120+
} else if (field is ExtendApiBase) {
121+
element.data = "extendApi|${clazzName}|${name}"
114122
}
115123
if (field.isDeprecated) {
116124
element.deprecated = true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.tang.lsp
2+
3+
interface ExtendApiBase {
4+
fun getComment(): String
5+
fun getLocation(): String
6+
}

EmmyLua-Common/src/main/resources/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<extensions defaultExtensionNs="com.tang.intellij.lua">
1010
<luaTypeInfer implementation="com.tang.intellij.lua.ty.LuaTypeInfer" id="base"/>
1111
<luaShortNamesManager implementation="com.tang.intellij.lua.psi.search.LuaShortNamesManagerImpl" id="base"/>
12+
<luaShortNamesManager implementation="com.tang.vscode.extendApi.ExtendShortNameManager" id="base2"/>
1213
<luaFileResolver implementation="com.tang.vscode.LuaFileResolver" id="base"/>
1314
</extensions>
1415
</plugin>

EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaLanguageClient.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package com.tang.vscode
44

5+
import com.tang.vscode.extendApi.LuaReportApiParams
56
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
67
import org.eclipse.lsp4j.services.LanguageClient
78

@@ -14,4 +15,7 @@ interface LuaLanguageClient : LanguageClient {
1415

1516
@JsonNotification("emmy/progressReport")
1617
fun progressReport(report: ProgressReport)
18+
19+
@JsonNotification("emmy/reportAPI")
20+
fun reportAPI(params: LuaReportApiParams)
1721
}

EmmyLua-LS/src/main/kotlin/com/tang/vscode/LuaTextDocumentService.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ import com.tang.intellij.lua.reference.ReferencesSearch
1818
import com.tang.intellij.lua.search.SearchContext
1919
import com.tang.intellij.lua.stubs.index.LuaClassMemberIndex
2020
import com.tang.intellij.lua.ty.*
21-
import com.tang.lsp.ILuaFile
22-
import com.tang.lsp.getRangeInFile
23-
import com.tang.lsp.nameRange
24-
import com.tang.lsp.toRange
21+
import com.tang.lsp.*
2522
import com.tang.vscode.api.impl.LuaFile
2623
//import com.tang.vscode.color.ColorService
2724
import com.tang.vscode.documentation.LuaDocumentationProvider
@@ -69,8 +66,8 @@ class LuaTextDocumentService(private val workspace: LuaWorkspaceService) : TextD
6966
@Suppress("unused")
7067
@JsonRequest("emmy/reportAPI")
7168
fun reportAPI(params: LuaReportApiParams): CompletableFuture<Boolean> {
72-
return computeAsync { checker->
73-
ExtendApiService.loadApi(params)
69+
return computeAsync { checker ->
70+
ExtendApiService.loadApi(workspace.getProject(), params)
7471
true
7572
}
7673
}
@@ -206,7 +203,7 @@ class LuaTextDocumentService(private val workspace: LuaWorkspaceService) : TextD
206203
val data = item.data
207204
if (data is JsonPrimitive) {
208205
val arr = data.asString.split("|")
209-
if (arr.size >= 2) {
206+
if (arr.size == 2) {
210207
val file = workspace.findLuaFile(arr[0])
211208
if (file is ILuaFile) {
212209
file.lock {
@@ -222,6 +219,14 @@ class LuaTextDocumentService(private val workspace: LuaWorkspaceService) : TextD
222219
}
223220
}
224221
}
222+
} else if (arr.size == 3 && arr[0] == "extendApi") {
223+
val doc = documentProvider.generateExtendDoc(arr[1], arr[2])
224+
if(doc != null) {
225+
val content = MarkupContent()
226+
content.kind = "markdown"
227+
content.value = doc
228+
item.documentation = Either.forRight(content)
229+
}
225230
}
226231
}
227232
item

EmmyLua-LS/src/main/kotlin/com/tang/vscode/documentation/DocRenderer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ inline fun StringBuilder.wrapTag(tag: String, crossinline body: () -> Unit) {
3838
}
3939

4040
inline fun StringBuilder.wrapLanguage(language: String, crossinline body: () -> Unit) {
41-
wrap("```${language}\n", "\n```\n***\n", body)
41+
wrap("```${language}\n", "\n```\n\n", body)
4242
}
4343

4444
internal fun StringBuilder.appendClassLink(clazz: String) {

EmmyLua-LS/src/main/kotlin/com/tang/vscode/documentation/LuaDocumentationProvider.kt

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import com.tang.intellij.lua.reference.ReferencesSearch
2727
import com.tang.intellij.lua.search.SearchContext
2828
import com.tang.intellij.lua.stubs.index.LuaClassIndex
2929
import com.tang.intellij.lua.ty.*
30+
import com.tang.lsp.ExtendApiBase
31+
import com.tang.vscode.extendApi.ExtendApiService
32+
3033

3134
/**
3235
* Documentation support
@@ -105,6 +108,17 @@ class LuaDocumentationProvider : DocumentationProvider {
105108
return ""
106109
}
107110

111+
fun generateExtendDoc(clazzName: String, memberName: String): String? {
112+
val clazz = ExtendApiService.getNsMember(clazzName)
113+
if (clazz != null) {
114+
val member = clazz.findMember(memberName)
115+
if (member != null) {
116+
return generateDoc(member)
117+
}
118+
}
119+
return null
120+
}
121+
108122
private fun renderClassMember(sb: StringBuilder, classMember: LuaClassMember) {
109123
val context = SearchContext.get(classMember.project)
110124
val parentType = classMember.guessClassType(context)
@@ -114,29 +128,23 @@ class LuaDocumentationProvider : DocumentationProvider {
114128
sb.wrapLanguage("lua") {
115129
when (classMember.visibility) {
116130
Visibility.PUBLIC -> {
117-
sb.append("(public) ")
131+
sb.append("public ")
118132
}
119133
Visibility.PRIVATE -> {
120-
sb.append("(private) ")
134+
sb.append("private ")
121135
}
122136
Visibility.PROTECTED -> {
123-
sb.append("(protected) ")
137+
sb.append("protected ")
124138
}
125139
}
126140
when (ty) {
127141
is TyFunction -> {
128-
sb.append("function ")
129-
if (parentType.displayName != "_G") {
130-
renderTy(sb, parentType)
131-
sb.append(if (ty.isColonCall) ":" else ".")
132-
}
133142
sb.append(classMember.name)
134143
renderSignature(sb, ty.mainSignature)
135144

136145
return@wrapLanguage
137146
}
138147
else -> {
139-
sb.append("field ")
140148
if (classMember.name != null && LuaConst.isConstField(
141149
parentType.className,
142150
classMember.name!!,
@@ -146,8 +154,7 @@ class LuaDocumentationProvider : DocumentationProvider {
146154
when (classMember) {
147155
is LuaTableField -> {
148156
if (classMember.exprList.isNotEmpty()) {
149-
renderTy(sb, parentType)
150-
sb.append(".${classMember.name} = ")
157+
sb.append("${classMember.name} = ")
151158
sb.append(classMember.exprList.first().text)
152159
return@wrapLanguage
153160
}
@@ -160,7 +167,10 @@ class LuaDocumentationProvider : DocumentationProvider {
160167
val values = assignStat.valueExprList?.exprList ?: listOf()
161168

162169
for (i in 0 until assignees.size) {
163-
if (assignees[i] == classMember && i < values.size && isConstLiteral(values[i])) {
170+
if (assignees[i] == classMember && i < values.size && isConstLiteral(
171+
values[i]
172+
)
173+
) {
164174
renderTy(sb, parentType)
165175
sb.append(".${classMember.name} = ${values[i].text}")
166176
sb.append("\n")
@@ -226,7 +236,9 @@ class LuaDocumentationProvider : DocumentationProvider {
226236
//comment content
227237
if (classMember is LuaCommentOwner)
228238
renderComment(sb, classMember.comment)
229-
else {
239+
else if (classMember is ExtendApiBase) {
240+
sb.append(classMember.getComment())
241+
} else {
230242
if (classMember is LuaDocTagField)
231243
renderCommentString(" ", null, sb, classMember.commentString)
232244
else if (classMember is LuaIndexExpr) {
Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,109 @@
11
package com.tang.vscode.extendApi
22

3+
import com.intellij.openapi.project.Project
4+
import com.intellij.psi.PsiManager
5+
import com.tang.intellij.lua.psi.LuaParamInfo
6+
import com.tang.intellij.lua.ty.FunSignature
7+
import com.tang.intellij.lua.ty.Ty
8+
import com.tang.intellij.lua.ty.TySerializedFunction
9+
310
object ExtendApiService {
4-
fun loadApi(api: LuaReportApiParams) {
5-
val a = 1
11+
private var rootNamespace: Namespace? = null
12+
private var namespaceMap: MutableMap<String, Namespace> = mutableMapOf()
13+
private var classMap: MutableMap<String, ExtendClass> = mutableMapOf()
14+
15+
fun loadApi(project: Project, api: LuaReportApiParams) {
16+
val mgr = PsiManager.getInstance(project)
17+
if (rootNamespace == null) {
18+
rootNamespace = Namespace("CS", null, mgr, false)
19+
}
20+
21+
for (luaClass in api.classes) {
22+
val classNs = getNamespace(luaClass.namespace)
23+
if (classNs != null) {
24+
val classFullName = if (luaClass.namespace.isEmpty()) {
25+
luaClass.name
26+
} else {
27+
"${luaClass.namespace}.${luaClass.name}"
28+
}
29+
val extendClass = ExtendClass(
30+
luaClass.name,
31+
classFullName,
32+
luaClass.baseClass,
33+
classNs,
34+
luaClass.comment,
35+
luaClass.location,
36+
mgr
37+
)
38+
classMap[classFullName] = extendClass
39+
classNs.addMember(extendClass)
40+
for (luaField in luaClass.fields) {
41+
val ty = Ty.create(luaField.typeName)
42+
extendClass.addMember(luaField.name, ty, luaField.comment, luaField.location)
43+
}
44+
45+
for (luaMethod in luaClass.methods) {
46+
val paramList = mutableListOf<LuaParamInfo>()
47+
for (param in luaMethod.params) {
48+
paramList.add(LuaParamInfo(param, Ty.create("any")))
49+
}
50+
51+
val retType = Ty.create(luaMethod.returnTypeName)
52+
val ty = TySerializedFunction(
53+
FunSignature(
54+
!luaMethod.isStatic,
55+
retType,
56+
null,
57+
paramList.toTypedArray()
58+
),
59+
emptyArray()
60+
)
61+
extendClass.addMember(luaMethod.name, ty, luaMethod.comment, luaMethod.location)
62+
}
63+
}
64+
}
65+
}
66+
67+
fun getExtendClasses(): MutableMap<String, ExtendClass> {
68+
return classMap
69+
}
70+
71+
fun getNsMember(name: String): NsMember? {
72+
if (name == "_G" || name == "CS") {
73+
return rootNamespace
74+
}
75+
76+
var member: NsMember? = namespaceMap[name]
77+
if (member != null) {
78+
return member
79+
}
80+
81+
member = classMap[name]
82+
if (member != null) {
83+
return member
84+
}
85+
return null
86+
}
87+
88+
private fun getNamespace(nsName: String): Namespace? {
89+
if (nsName.isEmpty()) {
90+
return rootNamespace
91+
}
92+
val result = namespaceMap[nsName]
93+
if (result != null) {
94+
return result
95+
}
96+
97+
var prevNs = rootNamespace
98+
val nsParts = nsName.split('.')
99+
for (ns in nsParts) {
100+
prevNs = prevNs?.getOrPut(ns)
101+
}
102+
if (prevNs != null) {
103+
namespaceMap[nsName] = prevNs
104+
}
105+
106+
return prevNs
6107
}
108+
7109
}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
package com.tang.vscode.extendApi
22

3-
open class LuaApiBase(val Name: String = "", val Comment: String = "", val Location: String = "")
3+
open class LuaApiBase(val name: String = "", val comment: String = "", val location: String = "")
44

5-
data class LuaApiField(val TypeName: String = "") : LuaApiBase()
5+
data class LuaApiField(val typeName: String) : LuaApiBase()
66

77
data class LuaApiMethod(
8-
val ReturnTypeName: String = "",
9-
val TypeName: String = "",
10-
val IsStatic: Boolean = false,
11-
val Params: Array<String> = arrayOf()
8+
val returnTypeName: String,
9+
val typeName: String,
10+
val isStatic: Boolean,
11+
val params: List<String>
1212
) : LuaApiBase()
1313

1414
data class LuaApiClass(
15-
val namespace: String = "",
16-
val BaseClass: String = "",
17-
val Fields: Array<LuaApiField> = arrayOf(),
18-
val Methods: Array<LuaApiMethod> = arrayOf()
15+
val namespace: String,
16+
val baseClass: String,
17+
val fields: List<LuaApiField>,
18+
val methods: List<LuaApiMethod>
1919
) : LuaApiBase()
2020

21-
class LuaReportApiParams{
22-
val classes: Array<LuaApiClass> = arrayOf()
23-
}
21+
data class LuaReportApiParams(
22+
val classes: List<LuaApiClass>
23+
)

0 commit comments

Comments
 (0)