Skip to content

Commit 914cece

Browse files
committed
sync lsp.getProperties api change in xgolsw
1 parent f9f6404 commit 914cece

File tree

8 files changed

+68
-29
lines changed

8 files changed

+68
-29
lines changed

spx-gui/src/components/editor/code-editor/spx-code-editor/api-reference/index.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {
1414
APIReferenceContext
1515
} from '../../xgo-code-editor'
1616
import { mainCategories, subCategories } from '../../xgo-code-editor/common'
17-
import { isTextDocumentStageCode } from '../common'
17+
import { isTextDocumentStageCode, parseDefinitionName } from '../common'
1818
import iconEvent from './icons/event.svg?raw'
1919
import iconLook from './icons/look.svg?raw'
2020
import iconMotion from './icons/motion.svg?raw'
@@ -302,18 +302,12 @@ const categoryViewInfos: APICategoryViewInfo[] = [
302302
export class SpxAPIReferenceProvider implements IAPIReferenceProvider {
303303
constructor(private documentBase: DocumentBase) {}
304304

305-
private parseName(name: string | undefined): [receiver: string | null, method: string] {
306-
const parts = (name ?? '').split('.')
307-
if (parts.length > 1) return [parts[0], parts[1]]
308-
return [null, parts[0]]
309-
}
310-
311305
private getStageAPIReferenceItems = once(async () => {
312306
const maybeItems = await Promise.all(apiReferenceItems.map((id) => this.documentBase.getDocumentation(id)))
313307
const allItems = maybeItems.filter((i) => i != null) as DefinitionDocumentationItem[]
314308
return allItems.filter((item) => {
315309
if (item.definition.package !== packageSpx) return true
316-
const [receiver] = this.parseName(item.definition.name)
310+
const [receiver] = parseDefinitionName(item.definition.name)
317311
return receiver !== 'Sprite'
318312
})
319313
})
@@ -322,13 +316,13 @@ export class SpxAPIReferenceProvider implements IAPIReferenceProvider {
322316
const maybeItems = await Promise.all(apiReferenceItems.map((id) => this.documentBase.getDocumentation(id)))
323317
const allItems = maybeItems.filter((i) => i != null) as DefinitionDocumentationItem[]
324318
const spriteMethods = allItems.reduce((set, item) => {
325-
const [receiver, method] = this.parseName(item.definition.name)
319+
const [receiver, method] = parseDefinitionName(item.definition.name)
326320
if (receiver === 'Sprite') set.add(method)
327321
return set
328322
}, new Set<string>())
329323
return allItems.filter((item) => {
330324
if (item.definition.package !== packageSpx) return true
331-
const [receiver, method] = this.parseName(item.definition.name)
325+
const [receiver, method] = parseDefinitionName(item.definition.name)
332326
if (receiver === 'Game' && spriteMethods.has(method)) return false
333327
return true
334328
})

spx-gui/src/components/editor/code-editor/spx-code-editor/common.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import {
2424
type ResourceIdentifier,
2525
type TextDocumentIdentifier,
2626
getCodeFilePath,
27-
type Property
27+
type Property,
28+
type DefinitionIdentifier
2829
} from '../xgo-code-editor'
2930

3031
export type { ResourceModel }
@@ -182,6 +183,24 @@ export function textDocumentId2CodeFileName(id: TextDocumentIdentifier) {
182183
}
183184
}
184185

186+
/**
187+
* Parse receiver & method in `DefinitionIdentifier.name`.
188+
* For example:
189+
* - 'Game.timer' => ['Game', 'timer']
190+
* - 'Sprite.heading' => ['Sprite', 'heading']
191+
* - 'hour' => [null, 'hour']
192+
*/
193+
export function parseDefinitionName(name: string | undefined): [receiver: string | null, method: string] {
194+
const parts = (name ?? '').split('.')
195+
if (parts.length > 1) return [parts[0], parts[1]]
196+
return [null, parts[0]]
197+
}
198+
199+
export function isStageDefinition(definition: DefinitionIdentifier) {
200+
const [receiver] = parseDefinitionName(definition.name)
201+
return receiver === 'Game'
202+
}
203+
185204
export type { ColorValue }
186205

187206
export enum SpxInputType {
@@ -273,18 +292,20 @@ export async function getInvalidMonitors(
273292
invalidMonitors.push(monitor)
274293
continue
275294
}
276-
let propertyNames = propertyNamesMap.get(monitor.target)
277-
if (propertyNames == null) {
295+
let ownPropertyNames = propertyNamesMap.get(monitor.target)
296+
if (ownPropertyNames == null) {
278297
try {
279298
const properties = await getProperties(monitor.target, signal)
280-
propertyNames = new Set(properties.map((p) => p.name))
281-
propertyNamesMap.set(monitor.target, propertyNames)
299+
const ownProperties =
300+
monitor.target === '' ? properties : properties.filter((item) => !isStageDefinition(item.definition))
301+
ownPropertyNames = new Set(ownProperties.map((p) => p.name))
302+
propertyNamesMap.set(monitor.target, ownPropertyNames)
282303
} catch (e) {
283304
capture(e, `Failed to load properties for target: "${monitor.target}"`)
284305
continue
285306
}
286307
}
287-
if (!propertyNames.has(monitor.variableName)) {
308+
if (!ownPropertyNames.has(monitor.variableName)) {
288309
invalidMonitors.push(monitor)
289310
}
290311
}

spx-gui/src/components/editor/code-editor/spx-code-editor/ui/input-helper/SpxPropertyNameInput.vue

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,14 @@ const codeEditor = useCodeEditor()
4141
4242
const properties = ref<Property[]>([])
4343
44-
async function getProperties(textDocument: TextDocument, signal?: AbortSignal) {
44+
function getProperties(textDocument: TextDocument, signal?: AbortSignal) {
4545
const codeFilePath = getCodeFilePath(textDocument.id.uri)
4646
const isStage = stageCodeFilePaths.includes(codeFilePath)
4747
if (isStage) {
48-
return await codeEditor.getProperties('', signal)
48+
return codeEditor.getProperties('', signal)
4949
}
5050
const spriteName = codeFilePath.replace(/\.spx$/, '')
51-
const [stageProperties, spriteProperties] = await Promise.all([
52-
codeEditor.getProperties('', signal),
53-
codeEditor.getProperties(spriteName, signal)
54-
])
55-
const spritePropertyNames = new Set(spriteProperties.map((p) => p.name))
56-
return [...spriteProperties, ...stageProperties.filter((p) => !spritePropertyNames.has(p.name))]
51+
return codeEditor.getProperties(spriteName, signal)
5752
}
5853
5954
watchEffect(async (onCleanup) => {

spx-gui/src/components/editor/code-editor/xgo-code-editor/code-editor.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
toLSPPosition,
2121
type TextDocumentIdentifier,
2222
type ResourceIdentifier,
23+
DefinitionKind,
2324
fromLSPTextEdit,
2425
type Position,
2526
getTextDocumentId,
@@ -335,7 +336,23 @@ export class CodeEditor extends Disposable {
335336

336337
/** Get properties for a given target */
337338
async getProperties(target: string, signal?: AbortSignal): Promise<Property[]> {
338-
return this.lspClient.getProperties({ signal }, target)
339+
const properties = await this.lspClient.getProperties({ signal }, target)
340+
341+
const classFrameworkPkg = this.project.classFramework.pkgPaths[0]
342+
const maybeProperties = await Promise.all(
343+
properties.map(async (item) => {
344+
const documentation = await this.documentBase.getDocumentation(item.definition)
345+
// Skip APIs from framework packages without documentation — assumed not recommended
346+
if (item.definition.package === classFrameworkPkg && documentation == null) return null
347+
if (documentation != null) {
348+
if (documentation.hiddenFromList) return null
349+
if (![DefinitionKind.Read, DefinitionKind.Variable, DefinitionKind.Constant].includes(documentation.kind))
350+
return null
351+
}
352+
return item
353+
})
354+
)
355+
return maybeProperties.filter((item) => item != null)
339356
}
340357

341358
private uis: ICodeEditorUIController[] = []

spx-gui/src/components/editor/code-editor/xgo-code-editor/common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ export type Property = {
620620
kind: 'field' | 'method'
621621
/** Optional documentation for the property */
622622
doc?: string
623+
/** The definition identifier for the property */
624+
definition: DefinitionIdentifier
623625
}
624626

625627
export function positionEq(a: Position | null, b: Position | null) {

spx-gui/src/components/editor/stage/widget/detail/MonitorDetail.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ import { capture, useMessageHandle } from '@/utils/exception'
122122
import type { Monitor } from '@/models/spx/widget/monitor'
123123
import { useRenameWidget } from '@/components/asset'
124124
import { useEditorCtx } from '@/components/editor/EditorContextProvider.vue'
125-
import { useCodeEditor } from '@/components/editor/code-editor/spx-code-editor'
125+
import { isStageDefinition, useCodeEditor } from '@/components/editor/code-editor/spx-code-editor'
126126
import EditorItemDetail from '../../../common/EditorItemDetail.vue'
127127
import monitorIcon from '../monitor.svg?raw'
128128
@@ -140,11 +140,17 @@ const handleRename = useMessageHandle(() => renameWidget(props.monitor), {
140140
141141
const sprites = computed(() => editorCtx.project.sprites)
142142
143+
async function getOwnProperties(target: string, signal: AbortSignal) {
144+
const properties = await codeEditor.getProperties(target, signal)
145+
if (target === '') return properties
146+
return properties.filter((item) => !isStageDefinition(item.definition))
147+
}
148+
143149
const properties = useAsyncComputed(async (onCleanup) => {
144150
const target = props.monitor.target
145151
const signal = getCleanupSignal(onCleanup)
146152
try {
147-
return await codeEditor.getProperties(target, signal)
153+
return await getOwnProperties(target, signal)
148154
} catch (e) {
149155
capture(e, `Failed to load properties for target: "${target}"`)
150156
return []

tools/spxls/go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ tool github.com/goplus/xgolsw/cmd/pkgdatagen
66

77
require (
88
github.com/goplus/builder/tools/ai v0.0.0
9-
github.com/goplus/xgolsw v0.17.0
9+
github.com/goplus/xgolsw v0.17.1-0.20260327033750-feb54c4edc9e
1010
)
1111

1212
require (
1313
github.com/goplus/gogen v1.21.2 // indirect
1414
github.com/goplus/mod v0.19.6 // indirect
1515
github.com/goplus/spbase v0.1.0 // indirect
1616
github.com/goplus/spx/v2 v2.0.0-pre.48 // indirect
17-
github.com/goplus/xgo v1.6.6 // indirect
17+
github.com/goplus/xgo v1.6.7 // indirect
1818
github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e // indirect
1919
github.com/qiniu/x v1.16.5 // indirect
2020
golang.org/x/image v0.23.0 // indirect

tools/spxls/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ github.com/goplus/spx/v2 v2.0.0-pre.48 h1:7SOl5inDxCuKsvwWteWjIaB5csqZtlvt7lQ1Lx
1313
github.com/goplus/spx/v2 v2.0.0-pre.48/go.mod h1:oP0YVzWNrczCyyO8qjYyni5sV4wJ3sqVkjCmc+P6jBo=
1414
github.com/goplus/xgo v1.6.6 h1:gfFoGYnyGfImt1aFEkK55TQTzNUDZQYDlWq9mRr3ors=
1515
github.com/goplus/xgo v1.6.6/go.mod h1:7ViCaG6azWTPIxxvXPtkod7J13IO06qKWHJSaQ2nqvY=
16+
github.com/goplus/xgo v1.6.7 h1:vPKx5ddOmx93oSan0rXTKWk6RO2/gJowBew9GFrUNcU=
17+
github.com/goplus/xgo v1.6.7/go.mod h1:8wsvmW48dGeZ+rCMqlk/MsNecp/snz/tUqNkXaLoe6U=
1618
github.com/goplus/xgolsw v0.17.0 h1:IZvqYIsTCpfMrVvsb3JQMd0WvtZj9PNp0uooEX5PfSg=
1719
github.com/goplus/xgolsw v0.17.0/go.mod h1:R61Je+Ps3trGmRV1pambjv0o0PUfHD5MRnNL6G+GC88=
20+
github.com/goplus/xgolsw v0.17.1-0.20260327033750-feb54c4edc9e h1:d09IJ0zUTX4XPg6QilBVNpgx1WsQMYaW65579hOH7nk=
21+
github.com/goplus/xgolsw v0.17.1-0.20260327033750-feb54c4edc9e/go.mod h1:Gh43ivd+brouDLQxF5UGYCTOKvd9l7dRQtsoGX4J1V0=
1822
github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e h1:D0bJD+4O3G4izvrQUmzCL80zazlN7EwJ0PPDhpJWC/I=
1923
github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
2024
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

0 commit comments

Comments
 (0)