This commit is contained in:
parent
09fceca2f9
commit
40e5379eb3
11 changed files with 250 additions and 2 deletions
29
cmds/golines/format.go
Normal file
29
cmds/golines/format.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golangci/golines/shorten"
|
||||
)
|
||||
|
||||
func formatSource(source string, maxLen int) (output []byte, err error) {
|
||||
// Dependency panics must not escape the JS callback and terminate the WASM runtime.
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
output = nil
|
||||
err = fmt.Errorf("golines could not format this input (internal panic: %v). Ensure the input is a complete Go file, including a package declaration", recovered)
|
||||
}
|
||||
}()
|
||||
|
||||
tabLen := 4
|
||||
if maxLen < 80 {
|
||||
tabLen = 2
|
||||
}
|
||||
return shorten.NewShortener(&shorten.Config{
|
||||
MaxLen: maxLen,
|
||||
TabLen: tabLen,
|
||||
ShortenComments: true,
|
||||
ReformatTags: true,
|
||||
ChainSplitDots: true,
|
||||
}).Process([]byte(source))
|
||||
}
|
||||
45
cmds/golines/format_test.go
Normal file
45
cmds/golines/format_test.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFormatWidths(t *testing.T) {
|
||||
source := `package main
|
||||
func main() {
|
||||
println("first argument", "second argument", "third argument", "fourth argument")
|
||||
}
|
||||
`
|
||||
var narrow, wide string
|
||||
for width := 40; width <= 180; width += 5 {
|
||||
output, err := formatSource(source, width)
|
||||
if err != nil {
|
||||
t.Fatalf("width %d: %v", width, err)
|
||||
}
|
||||
if _, err := parser.ParseFile(token.NewFileSet(), "output.go", output, parser.AllErrors); err != nil {
|
||||
t.Fatalf("width %d produced invalid Go: %v", width, err)
|
||||
}
|
||||
if width == 40 {
|
||||
narrow = string(output)
|
||||
}
|
||||
if width == 180 {
|
||||
wide = string(output)
|
||||
}
|
||||
}
|
||||
if strings.Count(narrow, "\n") <= strings.Count(wide, "\n") {
|
||||
t.Fatal("narrow width did not split the call")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidSource(t *testing.T) {
|
||||
if _, err := formatSource("package main\nfunc {", 100); err == nil {
|
||||
t.Fatal("expected a syntax error")
|
||||
}
|
||||
// A failed edit must not prevent subsequent formatting.
|
||||
if _, err := formatSource("package main\nfunc main() {}", 100); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
40
cmds/golines/main.go
Normal file
40
cmds/golines/main.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//go:build js && wasm
|
||||
|
||||
package main
|
||||
|
||||
import "syscall/js"
|
||||
|
||||
func main() {
|
||||
document := js.Global().Get("document")
|
||||
element := func(id string) js.Value { return document.Call("getElementById", id) }
|
||||
source, width := element("source"), element("max-len")
|
||||
output, message := element("output"), element("message")
|
||||
render := func() {
|
||||
maxLen := width.Get("valueAsNumber").Int()
|
||||
element("width-value").Set("textContent", maxLen)
|
||||
tabLen := 4
|
||||
if maxLen < 80 {
|
||||
tabLen = 2
|
||||
}
|
||||
element("tab-value").Set("textContent", tabLen)
|
||||
source.Get("style").Set("tabSize", tabLen)
|
||||
output.Get("style").Set("tabSize", tabLen)
|
||||
formatted, err := formatSource(source.Get("value").String(), maxLen)
|
||||
if err != nil {
|
||||
output.Set("value", "")
|
||||
message.Set("textContent", err.Error())
|
||||
source.Call("setAttribute", "aria-invalid", "true")
|
||||
return
|
||||
}
|
||||
source.Call("removeAttribute", "aria-invalid")
|
||||
output.Set("value", string(formatted))
|
||||
message.Set("textContent", "")
|
||||
}
|
||||
listener := js.FuncOf(func(this js.Value, args []js.Value) any { render(); return nil })
|
||||
source.Call("addEventListener", "input", listener)
|
||||
width.Call("addEventListener", "input", listener)
|
||||
source.Set("disabled", false)
|
||||
width.Set("disabled", false)
|
||||
render()
|
||||
select {}
|
||||
}
|
||||
25
cmds/golines/recovery_test.go
Normal file
25
cmds/golines/recovery_test.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFormatterPanicRecovery(t *testing.T) {
|
||||
// go/format accepts fragments, but dst v0.27.3 panics when golines
|
||||
// attempts to decorate this function without a package declaration.
|
||||
source := `func example() {
|
||||
println("first argument", "second argument", "third argument", "fourth argument")
|
||||
}`
|
||||
output, err := formatSource(source, 40)
|
||||
if err == nil || !strings.Contains(err.Error(), "internal panic") {
|
||||
t.Fatalf("expected recovered dependency panic, got output %q, error %v", output, err)
|
||||
}
|
||||
if output != nil {
|
||||
t.Fatalf("unexpected output after panic: %q", output)
|
||||
}
|
||||
output, err = formatSource("package main\n"+source, 40)
|
||||
if err != nil || !strings.Contains(string(output), "func example()") {
|
||||
t.Fatalf("formatting after panic failed: output %q, error %v", output, err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue