Skip to content

Commit b80a24d

Browse files
committed
Merge branch 'main' into feat/twig-block-versioning
2 parents 4aa07ba + 0c002de commit b80a24d

56 files changed

Lines changed: 66266 additions & 38544 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

LSP.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ This document lists the custom LSP commands and notifications provided by the Sh
1414
* **Action:** Returns all detected Shopware extensions via the `ExtensionIndexer`.
1515
* **Returns:** array of objects with `Name`, `Type` and `Path` fields.
1616

17-
### `shopware/snippet/getPossibleSnippetFilse`
17+
### `shopware/snippet/storefront/getPossibleSnippetFiles`
1818
* **Parameters:** `{ "fileUri": string }`
1919
* **Action:** Searches the snippet directory for JSON files or creates a default `storefront.en-GB.json` if none exist.
2020
* **Returns:** `{ "paths": [ { "path": string, "name": string, "value": string } ] }`
2121

22-
### `shopware/snippet/create`
22+
### `shopware/snippet/storefront/create`
2323
* **Parameters:**
2424
```json
2525
{
@@ -31,9 +31,31 @@ This document lists the custom LSP commands and notifications provided by the Sh
3131
* **Action:** Adds the provided snippet value to the given JSON files, reindexes them and publishes diagnostics for the original document.
3232
* **Returns:** `null`
3333

34-
### `shopware/snippet/all`
34+
### `shopware/snippet/storefront/all`
3535
* **Parameters:** none
36-
* **Action:** Collects all snippet keys from the indexed snippet files.
36+
* **Action:** Collects all storefront snippet keys from the indexed snippet files.
37+
* **Returns:** array of objects `{ key, text, file }` sorted alphabetically.
38+
39+
### `shopware/snippet/admin/getPossibleSnippetFiles`
40+
* **Parameters:** `{ "fileUri": string }`
41+
* **Action:** Searches the administration snippet directory for JSON files or creates a default structure if none exist.
42+
* **Returns:** `{ "paths": [ { "path": string, "name": string, "value": string } ] }`
43+
44+
### `shopware/snippet/admin/create`
45+
* **Parameters:**
46+
```json
47+
{
48+
"fileUri": string,
49+
"snippetKey": string,
50+
"snippets": [ { "path": string, "name": string, "value": string } ]
51+
}
52+
```
53+
* **Action:** Adds the provided snippet value to the given admin JSON files, reindexes them and publishes diagnostics for the original document.
54+
* **Returns:** `null`
55+
56+
### `shopware/snippet/admin/all`
57+
* **Parameters:** none
58+
* **Action:** Collects all admin snippet keys from the indexed snippet files.
3759
* **Returns:** array of objects `{ key, text, file }` sorted alphabetically.
3860

3961
### `shopware/twig/extendBlock`

cmd/debug_ast/main.go

Lines changed: 149 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,163 @@
11
package main
22

33
import (
4+
"flag"
45
"fmt"
6+
"io"
57
"os"
8+
"path/filepath"
9+
"strings"
610

7-
"github.com/shopware/shopware-lsp/internal/php"
11+
tree_sitter_twig "github.com/shopware/shopware-lsp/internal/tree_sitter_grammars/twig/bindings/go"
12+
tree_sitter "github.com/tree-sitter/go-tree-sitter"
13+
tree_sitter_javascript "github.com/tree-sitter/tree-sitter-javascript/bindings/go"
14+
tree_sitter_json "github.com/tree-sitter/tree-sitter-json/bindings/go"
15+
tree_sitter_php "github.com/tree-sitter/tree-sitter-php/bindings/go"
816
)
917

1018
func main() {
11-
if len(os.Args) < 2 {
12-
fmt.Println("Usage: go run cmd/debug_ast/main.go <php_file_path>")
19+
lang := flag.String("lang", "", "Language to parse (php, js, twig, json). Auto-detected from extension if not specified.")
20+
flag.Parse()
21+
22+
args := flag.Args()
23+
if len(args) < 1 {
24+
fmt.Println("Usage: go run cmd/debug_ast/main.go [-lang=php|js|twig|json] <file_path>")
25+
fmt.Println(" go run cmd/debug_ast/main.go [-lang=php|js|twig|json] - < input.txt")
26+
fmt.Println("")
27+
fmt.Println("Options:")
28+
fmt.Println(" -lang Language to parse (php, js, twig, json)")
29+
fmt.Println(" Auto-detected from file extension if not specified")
30+
fmt.Println("")
31+
fmt.Println("Examples:")
32+
fmt.Println(" go run cmd/debug_ast/main.go example.php")
33+
fmt.Println(" go run cmd/debug_ast/main.go -lang=js example.vue")
34+
fmt.Println(" echo \"this.\\$tc('key')\" | go run cmd/debug_ast/main.go -lang=js -")
35+
os.Exit(1)
36+
}
37+
38+
filePath := args[0]
39+
40+
var fileContent []byte
41+
var err error
42+
43+
if filePath == "-" {
44+
// Read from stdin
45+
fileContent, err = io.ReadAll(os.Stdin)
46+
if err != nil {
47+
fmt.Printf("Error reading stdin: %v\n", err)
48+
os.Exit(1)
49+
}
50+
fmt.Println("Analyzing AST from stdin")
51+
} else {
52+
fileContent, err = os.ReadFile(filePath)
53+
if err != nil {
54+
fmt.Printf("Error reading file: %v\n", err)
55+
os.Exit(1)
56+
}
57+
fmt.Printf("Analyzing AST for file: %s\n\n", filePath)
58+
}
59+
60+
// Determine language
61+
language := *lang
62+
if language == "" && filePath != "-" {
63+
language = detectLanguage(filePath)
64+
}
65+
66+
if language == "" {
67+
fmt.Println("Error: Could not detect language. Please specify -lang flag.")
68+
os.Exit(1)
69+
}
70+
71+
parser := tree_sitter.NewParser()
72+
defer parser.Close()
73+
74+
var langErr error
75+
switch strings.ToLower(language) {
76+
case "php":
77+
langErr = parser.SetLanguage(tree_sitter.NewLanguage(tree_sitter_php.LanguagePHP()))
78+
case "js", "javascript":
79+
langErr = parser.SetLanguage(tree_sitter.NewLanguage(tree_sitter_javascript.Language()))
80+
case "twig":
81+
langErr = parser.SetLanguage(tree_sitter.NewLanguage(tree_sitter_twig.Language()))
82+
case "json":
83+
langErr = parser.SetLanguage(tree_sitter.NewLanguage(tree_sitter_json.Language()))
84+
default:
85+
fmt.Printf("Error: Unsupported language '%s'. Supported: php, js, twig, json\n", language)
86+
os.Exit(1)
87+
}
88+
89+
if langErr != nil {
90+
fmt.Printf("Error setting language: %v\n", langErr)
1391
os.Exit(1)
1492
}
1593

16-
filePath := os.Args[1]
17-
fmt.Printf("Analyzing AST for file: %s\n\n", filePath)
94+
tree := parser.Parse(fileContent, nil)
95+
if tree == nil {
96+
fmt.Println("Error: Failed to parse content")
97+
os.Exit(1)
98+
}
99+
defer tree.Close()
100+
101+
fmt.Printf("Language: %s\n", language)
102+
fmt.Printf("Content:\n---\n%s\n---\n\n", string(fileContent))
103+
104+
printNodeStructure(tree.RootNode(), fileContent, 0)
105+
}
18106

19-
php.DebugAST(filePath)
107+
func detectLanguage(filePath string) string {
108+
ext := strings.ToLower(filepath.Ext(filePath))
109+
switch ext {
110+
case ".php":
111+
return "php"
112+
case ".js", ".mjs", ".cjs":
113+
return "js"
114+
case ".twig":
115+
return "twig"
116+
case ".json":
117+
return "json"
118+
default:
119+
return ""
120+
}
121+
}
122+
123+
func printNodeStructure(node *tree_sitter.Node, fileContent []byte, depth int) {
124+
if node == nil {
125+
return
126+
}
127+
128+
indent := ""
129+
for i := 0; i < depth; i++ {
130+
indent += " "
131+
}
132+
133+
// Get position info
134+
startPos := node.StartPosition()
135+
endPos := node.EndPosition()
136+
137+
nodeText := ""
138+
if node.NamedChildCount() == 0 {
139+
text := string(node.Utf8Text(fileContent))
140+
// Truncate long text
141+
if len(text) > 50 {
142+
text = text[:47] + "..."
143+
}
144+
// Escape newlines for display
145+
text = strings.ReplaceAll(text, "\n", "\\n")
146+
text = strings.ReplaceAll(text, "\r", "\\r")
147+
text = strings.ReplaceAll(text, "\t", "\\t")
148+
nodeText = fmt.Sprintf(" = %q", text)
149+
}
150+
151+
fmt.Printf("%s%s [%d:%d-%d:%d]%s\n",
152+
indent,
153+
node.Kind(),
154+
startPos.Row, startPos.Column,
155+
endPos.Row, endPos.Column,
156+
nodeText,
157+
)
158+
159+
// Recursively print child nodes
160+
for i := uint(0); i < node.NamedChildCount(); i++ {
161+
printNodeStructure(node.NamedChild(i), fileContent, depth+1)
162+
}
20163
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/tree-sitter-grammars/tree-sitter-xml v0.7.0
1717
github.com/tree-sitter-grammars/tree-sitter-yaml v0.7.2
1818
github.com/tree-sitter/go-tree-sitter v0.25.0
19+
github.com/tree-sitter/tree-sitter-javascript v0.25.0
1920
github.com/tree-sitter/tree-sitter-json v0.24.8
2021
github.com/tree-sitter/tree-sitter-php v0.24.2
2122
github.com/vmihailenco/msgpack/v5 v5.4.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ github.com/tree-sitter/tree-sitter-html v0.23.2 h1:1UYDV+Yd05GGRhVnTcbP58GkKLSHH
5959
github.com/tree-sitter/tree-sitter-html v0.23.2/go.mod h1:gpUv/dG3Xl/eebqgeYeFMt+JLOY9cgFinb/Nw08a9og=
6060
github.com/tree-sitter/tree-sitter-java v0.23.5 h1:J9YeMGMwXYlKSP3K4Us8CitC6hjtMjqpeOf2GGo6tig=
6161
github.com/tree-sitter/tree-sitter-java v0.23.5/go.mod h1:NRKlI8+EznxA7t1Yt3xtraPk1Wzqh3GAIC46wxvc320=
62-
github.com/tree-sitter/tree-sitter-javascript v0.23.1 h1:1fWupaRC0ArlHJ/QJzsfQ3Ibyopw7ZfQK4xXc40Zveo=
63-
github.com/tree-sitter/tree-sitter-javascript v0.23.1/go.mod h1:lmGD1EJdCA+v0S1u2fFgepMg/opzSg/4pgFym2FPGAs=
62+
github.com/tree-sitter/tree-sitter-javascript v0.25.0 h1:ZkWETb66/w8cc13yhfnNuHOLDQWl3BnKlH6f9AdR88c=
63+
github.com/tree-sitter/tree-sitter-javascript v0.25.0/go.mod h1:lmGD1EJdCA+v0S1u2fFgepMg/opzSg/4pgFym2FPGAs=
6464
github.com/tree-sitter/tree-sitter-json v0.24.8 h1:tV5rMkihgtiOe14a9LHfDY5kzTl5GNUYe6carZBn0fQ=
6565
github.com/tree-sitter/tree-sitter-json v0.24.8/go.mod h1:F351KK0KGvCaYbZ5zxwx/gWWvZhIDl0eMtn+1r+gQbo=
6666
github.com/tree-sitter/tree-sitter-php v0.24.2 h1:yy+COnaaHUNDTKODfNbHhVRD4mQpFELTnBK9+EhpO+w=

internal/admin/component.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package admin
2+
3+
// VueComponent represents a Shopware 6 Admin Vue component
4+
type VueComponent struct {
5+
// Name is the component name (e.g., "sw-base-filter")
6+
Name string
7+
8+
// ExtendsComponent is the parent component name if this component extends another (empty for register)
9+
ExtendsComponent string
10+
11+
// ImportPath is the path from the import statement (e.g., "src/app/component/filter/sw-base-filter/index")
12+
ImportPath string
13+
14+
// FilePath is the absolute path to the registration file
15+
FilePath string
16+
17+
// DefinitionPath is the resolved absolute path to the component definition file
18+
DefinitionPath string
19+
20+
// Line is the line number where the component is registered
21+
Line int
22+
23+
// Props contains the component's props definitions
24+
Props []VueComponentProp
25+
26+
// Emits contains the component's emitted events
27+
Emits []string
28+
29+
// Methods contains the component's method names
30+
Methods []string
31+
32+
// Computed contains the component's computed property names
33+
Computed []string
34+
35+
// Slots contains the component's slot definitions
36+
Slots []VueComponentSlot
37+
38+
// Blocks contains the component's Twig block definitions
39+
Blocks []TwigBlock
40+
41+
// TemplatePath is the path to the Twig template (from the template import)
42+
TemplatePath string
43+
44+
// InlineDefinition contains the parsed definition for inline component registrations
45+
// This is only populated during indexing and not persisted (used to store in definition index)
46+
InlineDefinition *ComponentDefinition `msgpack:"-"`
47+
}
48+
49+
// VueComponentProp represents a prop definition in a Vue component
50+
type VueComponentProp struct {
51+
// Name is the prop name
52+
Name string
53+
54+
// Type is the prop type (e.g., "String", "Boolean", "Object")
55+
Type string
56+
57+
// Required indicates if the prop is required
58+
Required bool
59+
60+
// Default is the default value (as string representation)
61+
Default string
62+
63+
// Line is the line number where the prop is defined (1-based)
64+
Line int
65+
}
66+
67+
// VueComponentSlot represents a slot definition in a Vue component template
68+
type VueComponentSlot struct {
69+
// Name is the slot name (e.g., "default", "actions", "header")
70+
Name string
71+
72+
// Line is the line number where the slot is defined in the template (1-based)
73+
Line int
74+
}
75+
76+
// TwigBlock represents a Twig block definition in a component template
77+
type TwigBlock struct {
78+
// Name is the block name (e.g., "sw_page_content", "sw_page_smart_bar")
79+
Name string
80+
81+
// Line is the line number where the block is defined in the template (1-based)
82+
Line int
83+
}

0 commit comments

Comments
 (0)