z_mirror/luapls

git clone https://git.raiguard.me/z_mirror/luapls

Caleb HeuerRemove scrapped file graph nonsense582fe74

main
3.3 KiB159 linesraw
1package main
2
3import (
4	"encoding/json"
5	"fmt"
6	"os"
7	"path/filepath"
8	"strconv"
9	"time"
10
11	"github.com/raiguard/luapls/lsp"
12	"github.com/raiguard/luapls/lua/ast"
13	"github.com/raiguard/luapls/lua/lexer"
14	"github.com/raiguard/luapls/lua/parser"
15	"github.com/raiguard/luapls/lua/token"
16	"github.com/raiguard/luapls/lua/types"
17	"github.com/raiguard/luapls/repl"
18	"github.com/tliron/kutil/util"
19)
20
21func main() {
22	args := os.Args
23	task := "lsp"
24	if len(args) > 1 {
25		task = args[1]
26	}
27
28	switch task {
29	case "lex":
30		if len(args) < 3 {
31			fmt.Fprintln(os.Stderr, "Did not provide a filename")
32			os.Exit(1)
33		}
34		lexFile(args[2])
35	case "lsp":
36		level := int64(0)
37		if len(args) > 2 {
38			level, _ = strconv.ParseInt(args[2], 0, 8)
39		}
40		lsp.Run(int(level))
41	case "parse":
42		if len(args) < 3 {
43			fmt.Fprintln(os.Stderr, "Did not provide a filename")
44			os.Exit(1)
45		}
46		parseFile(args[2])
47	case "make-test":
48		if len(args) < 4 {
49			fmt.Fprintln(os.Stderr, "Not enough arguments: luapls make-test <suite> <label> <input string>")
50			os.Exit(1)
51		}
52		makeTest(args[2], args[3], args[4])
53	case "repl":
54		repl.Run()
55	case "check":
56		check()
57	default:
58		fmt.Fprintf(os.Stderr, "%s: unrecognized subcommand\n", task)
59	}
60
61	util.Exit(0)
62}
63
64func lexFile(filename string) {
65	src, err := os.ReadFile(filename)
66	if err != nil {
67		panic(err)
68	}
69	l := lexer.New(string(src))
70	for {
71		tok := l.Next()
72		fmt.Println(tok.String())
73		if tok.Type == token.EOF || tok.Type == token.INVALID {
74			break
75		}
76	}
77	fmt.Println(l.GetLineBreaks())
78}
79
80func parseFile(filename string) {
81	before := time.Now()
82	src, err := os.ReadFile(filename)
83	if err != nil {
84		fmt.Fprintln(os.Stderr, err)
85		os.Exit(1)
86	}
87	// units, _ := parser.Run(string(src))
88	// bytes, err := json.MarshalIndent(units, "", "  ")
89	// if err != nil {
90	// 	panic(err)
91	// }
92	// fmt.Println(string(bytes))
93	p := parser.New(string(src))
94	file := p.ParseFile()
95	duration := time.Since(before)
96	bytes, err := json.MarshalIndent(struct {
97		Duration string
98		File     ast.File
99	}{
100		Duration: duration.String(),
101		File:     file,
102	}, "", "  ")
103	if err != nil {
104		fmt.Fprintln(os.Stderr, err)
105		os.Exit(1)
106	}
107	fmt.Println(string(bytes))
108}
109
110type testSpec struct {
111	Label  string
112	Input  string
113	AST    json.RawMessage
114	Errors json.RawMessage `json:",omitempty"`
115}
116
117func makeTest(suite string, label string, input string) {
118	p := parser.New(input)
119	file := p.ParseFile()
120	ast, _ := json.Marshal(&file.Block)
121	errors, _ := json.Marshal(p.Errors())
122	newSpec := testSpec{label, input, ast, errors}
123	path := filepath.Join("lua/parser/test_specs", suite+".json")
124	specs := readOrMakeSpecs(path)
125	specs = append(specs, newSpec)
126	output, _ := json.MarshalIndent(specs, "", "  ")
127	os.WriteFile(path, output, 0644)
128}
129
130func readOrMakeSpecs(path string) []testSpec {
131	specs := []testSpec{}
132	file, err := os.ReadFile(path)
133	if err == nil {
134		json.Unmarshal(file, &specs)
135	}
136	return specs
137}
138
139func check() {
140	env := types.NewEnvironment()
141	if env == nil {
142		panic("Failed to initialize environment")
143	}
144	env.RootPath = "."
145	env.Init()
146	fmt.Println("TYPES:")
147	for typName := range env.Types {
148		fmt.Printf("    %s\n", typName)
149	}
150	fmt.Println("DIAGNOSTICS:")
151	for uri, file := range env.Files {
152		if len(file.Diagnostics) > 0 {
153			fmt.Printf("    %s\n", uri)
154			for _, diag := range file.Diagnostics {
155				fmt.Printf("        %s: %s\n", diag.Range.String(), diag.Message)
156			}
157		}
158	}
159}