Skip to content

Commit

Permalink
debug api-reference (#1148)
Browse files Browse the repository at this point in the history
  • Loading branch information
nighca authored Dec 17, 2024
1 parent a635c99 commit 4520087
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 41 deletions.
69 changes: 61 additions & 8 deletions spx-gui/src/components/editor/code-editor/document-base/spx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ export const broadcast2: DefinitionDocumentationItem = {
})
}

export const onStart: DefinitionDocumentationItem = {
export const gameOnStart: DefinitionDocumentationItem = {
categories: [categories.event.game],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1097,7 +1097,15 @@ export const onStart: DefinitionDocumentationItem = {
})
}

export const onClickGame: DefinitionDocumentationItem = {
export const spriteOnStart: DefinitionDocumentationItem = {
...gameOnStart,
definition: {
package: packageSpx,
name: 'Sprite.onStart'
}
}

export const gameOnClick: DefinitionDocumentationItem = {
categories: [categories.event.sensing],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1112,7 +1120,7 @@ export const onClickGame: DefinitionDocumentationItem = {
})
}

export const onClickSprite: DefinitionDocumentationItem = {
export const spriteOnClick: DefinitionDocumentationItem = {
categories: [categories.event.sensing],
kind: DefinitionKind.Listen,
definition: {
Expand Down Expand Up @@ -1142,7 +1150,7 @@ export const onAnyKey: DefinitionDocumentationItem = {
})
}

export const onKey0: DefinitionDocumentationItem = {
export const gameOnKey0: DefinitionDocumentationItem = {
categories: [categories.event.sensing],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1158,7 +1166,7 @@ export const onKey0: DefinitionDocumentationItem = {
})
}

export const onKey1: DefinitionDocumentationItem = {
export const gameOnKey1: DefinitionDocumentationItem = {
categories: [categories.event.sensing],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1174,7 +1182,7 @@ export const onKey1: DefinitionDocumentationItem = {
})
}

export const onKey2: DefinitionDocumentationItem = {
export const gameOnKey2: DefinitionDocumentationItem = {
categories: [categories.event.sensing],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1190,7 +1198,34 @@ export const onKey2: DefinitionDocumentationItem = {
})
}

export const onMsg0: DefinitionDocumentationItem = {
export const spriteOnKey0: DefinitionDocumentationItem = {
...gameOnKey0,
definition: {
package: packageSpx,
name: 'Sprite.onKey',
overloadId: '0'
}
}

export const spriteOnKey1: DefinitionDocumentationItem = {
...gameOnKey1,
definition: {
package: packageSpx,
name: 'Sprite.onKey',
overloadId: '1'
}
}

export const spriteOnKey2: DefinitionDocumentationItem = {
...gameOnKey2,
definition: {
package: packageSpx,
name: 'Sprite.onKey',
overloadId: '2'
}
}

export const gameOnMsg0: DefinitionDocumentationItem = {
categories: [categories.event.message],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1206,7 +1241,7 @@ export const onMsg0: DefinitionDocumentationItem = {
})
}

export const onMsg1: DefinitionDocumentationItem = {
export const gameOnMsg1: DefinitionDocumentationItem = {
categories: [categories.event.message],
kind: DefinitionKind.Listen,
definition: {
Expand All @@ -1222,6 +1257,24 @@ export const onMsg1: DefinitionDocumentationItem = {
})
}

export const spriteOnMsg0: DefinitionDocumentationItem = {
...gameOnMsg0,
definition: {
package: packageSpx,
name: 'Sprite.onMsg',
overloadId: '0'
}
}

export const spriteOnMsg1: DefinitionDocumentationItem = {
...gameOnMsg1,
definition: {
package: packageSpx,
name: 'Sprite.onMsg',
overloadId: '1'
}
}

export const onBackdrop0: DefinitionDocumentationItem = {
categories: [categories.event.stage],
kind: DefinitionKind.Listen,
Expand Down
16 changes: 8 additions & 8 deletions tools/spxls/internal/server/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ func (s *Server) spxGetDefinitions(params []SpxGetDefinitionsParams) ([]SpxDefin
universalScope := result.mainPkg.Scope().Parent()

var definitions []SpxDefinitionIdentifier
addDefinition := func(pkg, name string, overloadIndex *int) {
addDefinition := func(pkg, name string, overloadId *string) {
def := SpxDefinitionIdentifier{
OverloadIndex: overloadIndex,
OverloadId: overloadId,
}
if pkg != "" {
def.Package = &pkg
Expand All @@ -141,7 +141,7 @@ func (s *Server) spxGetDefinitions(params []SpxGetDefinitionsParams) ([]SpxDefin
def.Name = &name
}
if !slices.ContainsFunc(definitions, func(def SpxDefinitionIdentifier) bool {
return fromStringPtr(def.Name) == name && fromIntPtr(def.OverloadIndex) == fromIntPtr(overloadIndex)
return fromStringPtr(def.Name) == name && fromStringPtr(def.OverloadId) == fromStringPtr(overloadId)
}) {
definitions = append(definitions, def)
}
Expand Down Expand Up @@ -240,7 +240,7 @@ func (s *Server) spxGetDefinitions(params []SpxGetDefinitionsParams) ([]SpxDefin
return
}

funcName, overloadIndex := parseGopFuncName(method.Name())
funcName, overloadId := parseGopFuncName(method.Name())
if _, ok := calledEventHandlers[named.String()+"."+funcName]; ok {
return
}
Expand All @@ -265,7 +265,7 @@ func (s *Server) spxGetDefinitions(params []SpxGetDefinitionsParams) ([]SpxDefin
}
}

addDefinition(methodPkgPath, receiverName+"."+funcName, overloadIndex)
addDefinition(methodPkgPath, receiverName+"."+funcName, overloadId)
},
)
}
Expand All @@ -276,13 +276,13 @@ func (s *Server) spxGetDefinitions(params []SpxGetDefinitionsParams) ([]SpxDefin
if obj := result.spxPkg.Scope().Lookup(name); obj != nil {
name := obj.Name()

var overloadIndex *int
var overloadId *string
if _, ok := obj.(*types.Func); ok {
name, overloadIndex = parseGopFuncName(name)
name, overloadId = parseGopFuncName(name)
}

if obj.Exported() {
addDefinition(spxPkgPath, name, overloadIndex)
addDefinition(spxPkgPath, name, overloadId)
}
}
}
Expand Down
89 changes: 70 additions & 19 deletions tools/spxls/internal/server/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ onStart => {
Name: toStringPtr("MySprite"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadId: toStringPtr("1"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.onStart"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadId: toStringPtr("1"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Expand All @@ -83,18 +83,18 @@ onStart => {
Name: toStringPtr("println"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mySpriteSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadId: toStringPtr("1"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mySpriteSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.onStart"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mySpriteSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadId: toStringPtr("1"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mySpriteSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Expand All @@ -117,24 +117,75 @@ onStart => {
Name: toStringPtr("println"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mySpriteSpxOnStartScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadId: toStringPtr("1"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mySpriteSpxOnStartScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.onStart"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mySpriteSpxOnStartScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadIndex: toIntPtr(1),
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.turn"),
OverloadId: toStringPtr("1"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mySpriteSpxOnStartScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.onStart"),
}))
})

t.Run("TrailingEmptyLinesOfSpriteCode", func(t *testing.T) {
s := New(vfs.NewMapFS(func() map[string][]byte {
return map[string][]byte{
"main.spx": []byte(`
var (
MySprite Sprite
)
MySprite.turn Left
run "assets", {Title: "My Game"}
`),
"MySprite.spx": []byte(`
onStart => {
MySprite.turn Right
}
`),
"assets/sprites/MySprite/index.json": []byte(`{}`),
}
}), nil)

mainSpxFileScopeParams := []SpxGetDefinitionsParams{
{
TextDocumentPositionParams: TextDocumentPositionParams{
TextDocument: TextDocumentIdentifier{URI: "file:///MySprite.spx"},
Position: Position{Line: 5, Character: 0},
},
},
}
mainSpxFileScopeDefs, err := s.spxGetDefinitions(mainSpxFileScopeParams)
require.NoError(t, err)
require.NotNil(t, mainSpxFileScopeDefs)
assert.True(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.play"),
OverloadId: toStringPtr("1"),
}))
assert.False(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Game.onStart"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.onStart"),
}))
assert.True(t, spxDefinitionIdentifierSliceContains(mainSpxFileScopeDefs, SpxDefinitionIdentifier{
Package: toStringPtr(spxPkgPath),
Name: toStringPtr("Sprite.onClick"),
}))
})
}

// spxDefinitionIdentifierSliceContains reports whether a slice of [SpxDefinitionIdentifier]
Expand All @@ -143,6 +194,6 @@ func spxDefinitionIdentifierSliceContains(defs []SpxDefinitionIdentifier, def Sp
return slices.ContainsFunc(defs, func(d SpxDefinitionIdentifier) bool {
return fromStringPtr(d.Package) == fromStringPtr(def.Package) &&
fromStringPtr(d.Name) == fromStringPtr(def.Name) &&
fromIntPtr(d.OverloadIndex) == fromIntPtr(def.OverloadIndex)
fromStringPtr(d.OverloadId) == fromStringPtr(def.OverloadId)
})
}
8 changes: 8 additions & 0 deletions tools/spxls/internal/server/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,15 @@ type compileResult struct {
// position. It returns nil if not found.
func (r *compileResult) innermostScopeAt(pos goptoken.Pos) *types.Scope {
var innermostScope *types.Scope
mainPkgScope := r.mainPkg.Scope()
// The `MainEntry` scope is the last child of the main package and covers all positions in the workspace.
// We need to skip `MainEntry` when searching for the innermost scope, as the file scope will be more precise.
// Especially for positions in trailing empty lines of a file, the file scope does not contain them in its position range.
mainEntryScope := mainPkgScope.Child(mainPkgScope.Len() - 1)
for _, scope := range r.typeInfo.Scopes {
if scope == mainEntryScope {
continue
}
if scope.Contains(pos) && (innermostScope == nil || innermostScope.Contains(scope.Pos())) {
innermostScope = scope
}
Expand Down
4 changes: 2 additions & 2 deletions tools/spxls/internal/server/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ type SpxDefinitionIdentifier struct {
// - `for_statement_with_single_condition`
Name *string `json:"name,omitempty"`

// Index in overloads.
OverloadIndex *int `json:"overloadIndex,omitempty"`
// Overload Identifier.
OverloadId *string `json:"overloadId,omitempty"`
}

// SpxResourceRefDocumentLinkData represents data for a spx resource reference
Expand Down
6 changes: 2 additions & 4 deletions tools/spxls/internal/server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"go/types"
"regexp"
"strconv"
"strings"

gopast "github.com/goplus/gop/ast"
Expand Down Expand Up @@ -145,12 +144,11 @@ func walkStruct(
var gopOverloadFuncNameRE = regexp.MustCompile(`^(.+)__(\d+)$`)

// parseGopFuncName parses the Go+ overloaded function name.
func parseGopFuncName(name string) (funcName string, overloadIndex *int) {
func parseGopFuncName(name string) (funcName string, overloadId *string) {
funcName = name
if matches := gopOverloadFuncNameRE.FindStringSubmatch(funcName); len(matches) == 3 {
funcName = matches[1]
idx, _ := strconv.Atoi(matches[2])
overloadIndex = &idx
overloadId = &matches[2]
}
funcName = strings.ToLower(string(funcName[0])) + funcName[1:] // Make it lowerCamelCase.
return
Expand Down
4 changes: 4 additions & 0 deletions tools/spxls/internal/vfs/mapfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io"
"io/fs"
"path"
"slices"
"strings"
"time"
)
Expand Down Expand Up @@ -112,6 +113,9 @@ func (mfs *MapFS) ReadDir(name string) ([]fs.DirEntry, error) {
isDir: false,
})
}
slices.SortFunc(entries, func(a, b fs.DirEntry) int {
return strings.Compare(a.Name(), b.Name())
})
return entries, nil
}

Expand Down

0 comments on commit 4520087

Please sign in to comment.