Skip to content

x/tools/gopls: Provide automatic conversion of structure A to structure B #65451

Open
@tttoad

Description

@tttoad

gopls version

Build info ---------- golang.org/x/tools/gopls v0.15.0-pre.1 golang.org/x/tools/gopls@v0.15.0-pre.1 h1:u87rDKpsE6ax0cASyD9mJW9If25TtW0IupV6vKDDevg= github.com/BurntSushi/toml@v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/google/go-cmp@v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= golang.org/x/exp/typeparams@v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW 6Y= golang.org/x/mod@v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/sync@v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/telemetry@v0.0.0-20231114163143-69313e640400 h1:brbkEFfGwNGAEkykUOcryE/JiHUMMJouzE0fWWmz/QU= golang.org/x/text@v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/tools@v0.16.2-0.20240105173808-36a523fefd90 h1:3dw2Y1Aes2o83VYvSZSPc+p70AuT9zvNCTBHCvUUZrE= golang.org/x/vuln@v1.0.1 h1:KUas02EjQK5LTuIx1OylBQdKKZ9jeugs+HiqO5HormU= honnef.co/go/tools@v0.4.5 h1:YGD4H+SuIOOqsyoLOpZDWcieM28W47/zRO7f+9V3nvo= mvdan.cc/gofumpt@v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= mvdan.cc/xurls/v2@v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc= go: go1.21.5

go env

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/toad/Library/Caches/go-build'
GOENV='/Users/toad/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/toad/work/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/toad/work'
GOPRIVATE=''
GOPROXY='https://goproxy.cn,direct'
GOROOT='/Users/toad/go/go1.21.5'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/toad/go/go1.21.5/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.5'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/toad/work/demo1/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-pref
ix-map=/var/folders/g1/tgmnlrdn3vxgv08kdgh9vpkw0000gn/T/go-build2737097617=/tmp/go-build -gno-record-gcc-switch
es -fno-common'

What did you do?

Call code actions in a=b

type AA struct {
	CCC string
	EEE string
	BBB int
}

type BB struct {
	CCC string
	BBB int 
	DDD string
}


func main() {
	var (
		a AA
		b BB
	)

	a=b
}

What did you see happen?

no code actions.

What did you expect to see?

There are code actions that support automatic conversion.

func main() {
	var (
		a AA
		b BB
	)

	a = AA{
		CCC: b.CCC,
		BBB: b.BBB,
	}
}

Editor and settings

No response

Logs

No response

Activity

added
goplsIssues related to the Go language server, gopls.
ToolsThis label describes issues relating to any tools in the x/tools repository.
on Feb 2, 2024
added this to the Unreleased milestone on Feb 2, 2024
tttoad

tttoad commented on Feb 2, 2024

@tttoad
Author

@gopherbot, please add label FeatureRequest

added
FeatureRequestIssues asking for a new feature that does not need a proposal.
on Feb 2, 2024
findleyr

findleyr commented on Feb 6, 2024

@findleyr
Member

Can you describe the precise way you'd like this feature to work? If there are any fields in b whose names match fields in a, generate a composite literal mapping those fields? What if there are methods with matching name and type on B, should we invoke them?

I feel like such a feature would be rarely needed. Do you find that you would use this feature often?

tttoad

tttoad commented on Feb 7, 2024

@tttoad
Author

@findleyr

I feel like such a feature would be rarely needed. Do you find that you would use this feature often?

Yes, I use this feature quite often.
In our service, different struct are used between different layers.
example:

// Request struct
type AddUser struct {
        Name  string
	Addr  string
	RequestID string // or other field.
}

// User Table struct
// This structure maps one-to-one to the database table fields.
type UserTable struct {
      Name string
      Addr  string
}

If there are any fields in b whose names match fields in a, generate a composite literal mapping those fields?

Yes.
It would be nice to deal with composite data structures.
Like B.UserID -> A.User.ID

type AA struct {
	User
}

type User struct{
         ID string
}

type BB struct {
	UserID string
}

a = AA{
	User: User{
		ID: b.UserID,
	},
}

What if there are methods with matching name and type on B, should we invoke them?

Yes.
It should support methods that start with Get.
I often need to convert structures in protobuf to my self.

tttoad

tttoad commented on Feb 17, 2024

@tttoad
Author

@findleyr Any news on this?
I am willing to provide the implementation of the feature if you agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeatureRequestIssues asking for a new feature that does not need a proposal.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @gopherbot@tttoad@findleyr

        Issue actions

          x/tools/gopls: Provide automatic conversion of structure A to structure B · Issue #65451 · golang/go