Skip to content

Commit

Permalink
goxls: format
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Oct 7, 2023
1 parent 3904cfa commit 5d09577
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 10 deletions.
3 changes: 3 additions & 0 deletions gopls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ require (
mvdan.cc/xurls/v2 v2.4.0
)

require github.com/qiniu/x v1.11.9 // indirect

require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/google/safehtml v0.1.0 // indirect
github.com/goplus/gop v1.1.7
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 // indirect

)
Expand Down
25 changes: 25 additions & 0 deletions gopls/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,71 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8=
github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
github.com/goplus/c2go v0.7.10/go.mod h1:ryOieVZqh0jmlPp45AMh9/sXIreTnyjDREP0EMX+pF0=
github.com/goplus/c2go v0.7.13/go.mod h1:s5NULWzUKi3erd3l4ahvpq+3qDGOvMjGb00a5o3h6zk=
github.com/goplus/gop v1.1.7 h1:6PemF6HYQZ2xjqIA06tQXk9LSmWz5p8+wo4UpQKTkes=
github.com/goplus/gop v1.1.7/go.mod h1:+kYk2ZSZ+rPD8AVoWTz3r5L/dkbtmUNvJOP0h1ET8KI=
github.com/goplus/gox v1.11.21/go.mod h1:wRCRSNukie4cDqADF4w0Btc2Gk6V3p3V6hI5+rsVqa8=
github.com/goplus/gox v1.11.32/go.mod h1:hdKq5ghywtKWnBJNQNVBkPITmWCqCFRwwd2LTYTfg2U=
github.com/goplus/gox v1.11.37/go.mod h1:NkgUJWIjKxrhUwM4bgyUt3ZE0WlTunqfksMzrbnh7V8=
github.com/goplus/libc v0.3.13/go.mod h1:xqG4/g3ilKBE/UDn5vkaE7RRQPQPyspj7ecuMuvlQJ8=
github.com/goplus/mod v0.9.12/go.mod h1:YoPIowz71rnLLROA4YG0AC8bzDtPRyMaQwgTRLr8ri4=
github.com/goplus/mod v0.11.2/go.mod h1:d40I3nOr2qkGfLUjwc/BqLSq3oUUlQy5+/SpdiBKgY4=
github.com/jba/printsrc v0.2.2 h1:9OHK51UT+/iMAEBlQIIXW04qvKyF3/vvLuwW/hL8tDU=
github.com/jba/printsrc v0.2.2/go.mod h1:1xULjw59sL0dPdWpDoVU06TIEO/Wnfv6AHRpiElTwYM=
github.com/jba/templatecheck v0.6.0 h1:SwM8C4hlK/YNLsdcXStfnHWE2HKkuTVwy5FKQHt5ro8=
github.com/jba/templatecheck v0.6.0/go.mod h1:/1k7EajoSErFI9GLHAsiIJEaNLt3ALKNw2TV7z2SYv4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/petermattis/goid v0.0.0-20220331194723-8ee3e6ded87a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qiniu/x v1.11.9 h1:IfQNdeNcK43Q1+b/LdrcqmWjlhxq051YVBnua8J2qN8=
github.com/qiniu/x v1.11.9/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/telemetry v0.0.0-20231003223302-0168ef4ebbd3 h1:vxxQvncMbcRAtqHV5HsHGJkbya+BIOYIY+y6cdPZhzk=
golang.org/x/telemetry v0.0.0-20231003223302-0168ef4ebbd3/go.mod h1:ppZ76JTkRgJC2GQEgtVY3fiuJR+N8FU2MAlp+gfN1E4=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
23 changes: 23 additions & 0 deletions gopls/internal/goxls/goputil/goputil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package goputil

type Kind int

const (
FileUnknown Kind = iota
FileGopNormal
FileGopClass
)

func FileKind(fext string) Kind {
switch fext {
case ".gop":
return FileGopNormal
case ".spx", ".rdx", ".gox", ".gmx":
return FileGopClass
}
return FileUnknown
}
7 changes: 2 additions & 5 deletions gopls/internal/lsp/cache/snapshot_gox.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
package cache

import (
"golang.org/x/tools/gopls/internal/goxls/goputil"
"golang.org/x/tools/gopls/internal/lsp/source"
)

func checkGopFile(fh source.FileHandle, fext string) bool {
switch fext {
case ".gop", ".spx", ".rdx", ".gox", ".gmx":
return true
}
return false
return goputil.FileKind(fext) != goputil.FileUnknown
}
2 changes: 1 addition & 1 deletion gopls/internal/lsp/code_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionPara

return actions, nil

case source.Go:
case source.Go, source.Gop: // goxls: Go+
diagnostics := params.Context.Diagnostics

// Don't suggest fixes for generated files, since they are generally
Expand Down
5 changes: 5 additions & 0 deletions gopls/internal/lsp/code_action_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lsp
2 changes: 1 addition & 1 deletion gopls/internal/lsp/code_lens.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams)
switch snapshot.FileKind(fh) {
case source.Mod:
lenses = mod.LensFuncs()
case source.Go:
case source.Go, source.Gop: // goxls: Go+
lenses = source.LensFuncs()
default:
// Unsupported file kind for a code lens.
Expand Down
5 changes: 5 additions & 0 deletions gopls/internal/lsp/code_lens_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lsp
2 changes: 1 addition & 1 deletion gopls/internal/lsp/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
var candidates []completion.CompletionItem
var surrounding *completion.Selection
switch snapshot.FileKind(fh) {
case source.Go:
case source.Go, source.Gop: // goxls: Go+
candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context)
case source.Mod:
candidates, surrounding = nil, nil
Expand Down
5 changes: 5 additions & 0 deletions gopls/internal/lsp/completion_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lsp
4 changes: 2 additions & 2 deletions gopls/internal/lsp/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (s *Server) definition(ctx context.Context, params *protocol.DefinitionPara
switch kind := snapshot.FileKind(fh); kind {
case source.Tmpl:
return template.Definition(snapshot, fh, params.Position)
case source.Go:
case source.Go, source.Gop: // goxls: Go+
return source.Definition(ctx, snapshot, fh, params.Position)
default:
return nil, fmt.Errorf("can't find definitions for file type %s", kind)
Expand All @@ -52,7 +52,7 @@ func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefini
return nil, err
}
switch kind := snapshot.FileKind(fh); kind {
case source.Go:
case source.Go, source.Gop: // goxls: Go+
return source.TypeDefinition(ctx, snapshot, fh, params.Position)
default:
return nil, fmt.Errorf("can't find type definitions for file type %s", kind)
Expand Down
5 changes: 5 additions & 0 deletions gopls/internal/lsp/difinition_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lsp
2 changes: 2 additions & 0 deletions gopls/internal/lsp/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormat
return mod.Format(ctx, snapshot, fh)
case source.Go:
return source.Format(ctx, snapshot, fh)
case source.Gop: // goxls: format Go+
return source.FormatGop(ctx, snapshot, fh)
case source.Work:
return work.Format(ctx, snapshot, fh)
}
Expand Down
5 changes: 5 additions & 0 deletions gopls/internal/lsp/format_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package lsp
98 changes: 98 additions & 0 deletions gopls/internal/lsp/source/format_gox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2023 The GoPlus Authors (goplus.org). All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package source

import (
"bytes"
"context"
"fmt"
"path/filepath"

"github.com/goplus/gop/format"
"golang.org/x/tools/gopls/internal/goxls/goputil"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/tokeninternal"
)

// FormatGop formats a file with a given range.
func FormatGop(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]protocol.TextEdit, error) {
ctx, done := event.Start(ctx, "gop.Format")
defer done()

// Generated files shouldn't be edited. So, don't format them
if IsGenerated(ctx, snapshot, fh.URI()) {
return nil, fmt.Errorf("can't format %q: file is generated", fh.URI().Filename())
}

pgf, err := snapshot.ParseGo(ctx, fh, ParseFull)
if err != nil {
return nil, err
}
// Even if this file has parse errors, it might still be possible to format it.
// Using format.Node on an AST with errors may result in code being modified.
// Attempt to format the source of this file instead.
if pgf.ParseErr != nil {
formatted, err := formatGopSource(ctx, fh)
if err != nil {
return nil, err
}
return computeTextEdits(ctx, snapshot, pgf, string(formatted))
}

// format.Node changes slightly from one release to another, so the version
// of Go used to build the LSP server will determine how it formats code.
// This should be acceptable for all users, who likely be prompted to rebuild
// the LSP server on each Go release.
buf := &bytes.Buffer{}
fset := tokeninternal.FileSetFor(pgf.Tok)
if err := format.Node(buf, fset, pgf.File); err != nil {
return nil, err
}
formatted := buf.String()

// Apply additional formatting, if any is supported. Currently, the only
// supported additional formatter is gofumpt.
if format := snapshot.Options().GofumptFormat; snapshot.Options().Gofumpt && format != nil {
// gofumpt can customize formatting based on language version and module
// path, if available.
//
// Try to derive this information, but fall-back on the default behavior.
//
// TODO: under which circumstances can we fail to find module information?
// Can this, for example, result in inconsistent formatting across saves,
// due to pending calls to packages.Load?
var langVersion, modulePath string
meta, err := NarrowestMetadataForFile(ctx, snapshot, fh.URI())
if err == nil {
if mi := meta.Module; mi != nil {
langVersion = mi.GoVersion
modulePath = mi.Path
}
}
b, err := format(ctx, langVersion, modulePath, buf.Bytes())
if err != nil {
return nil, err
}
formatted = string(b)
}
return computeTextEdits(ctx, snapshot, pgf, formatted)
}

func formatGopSource(ctx context.Context, fh FileHandle) ([]byte, error) {
_, done := event.Start(ctx, "gop.formatSource")
defer done()

data, err := fh.Content()
if err != nil {
return nil, err
}
return format.Source(data, isClass(fh))
}

func isClass(fh FileHandle) bool {
fext := filepath.Ext(fh.URI().Filename())
return goputil.FileKind(fext) == goputil.FileGopClass
}

0 comments on commit 5d09577

Please sign in to comment.